#c #class #templates #constexpr #compile-time
Вопрос:
Предположим, что у вас есть такой сценарий:
#include <array>
#include <cstdint>
template<typename T, std::size_t N>
struct A {
std::array<T, N> arr;
constexpr A(std::initializer_list<T> a) {
std::copy(a.begin(), a.end(), arr.begin());
}
constexpr A(auto rhs) {
std::copy(rhs.begin(), rhs.end(), arr.begin());
}
constexpr std::size_t countLeadingZeros(const autoamp; arr) const {
std::size_t count = 0;
for (std::size_t i = 0; i < arr.size(); i ) {
if (arr[i] == 0) { count ; }
}
return count;
}
constexpr auto operator (A rhs) const {
std::array<T, N> result_array;
result_array.fill(T{0});
for (std::size_t i = 0; i < N; i ) {
result_array[i] = arr[i] rhs.arr[i];
}
constexpr std::size_t zeros = countLeadingZeros(result_array);
std::array<T, zeros> arr;
return A(arr);
}
};
template<typename ... T>
A(T...) -> A<std::common_type_t<T...>, sizeof...(T)>;
int main() {
constexpr A a{1, 2, 3};
constexpr A b{4, 5, 6};
constexpr A c = a b;
return 0;
}
https://godbolt.org/z/q9T9WxxeY
Я хочу иметь возможность использовать нули в контексте времени компиляции, но поскольку result_array
это не constexpr, это не удается. Мой вопрос: Можно ли создать result_array
его во время компиляции для использования в качестве аргумента метода constexpr countLeadingZeros
?
Сообщения об ошибках компилятора являются:
error: constexpr variable 'zeros' must be initialized by a constant expression
constexpr std::size_t zeros = countLeadingZeros(result_array);
note: in instantiation of member function 'A<int, 3>::operator ' requested here
constexpr A c = a b;
note: implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
constexpr std::size_t zeros = countLeadingZeros(result_array);
Комментарии:
1.
result_array
зависит от параметраrhs
иthis
которые не являются/не могут быть constexpr. так что нет, как есть. вам понадобится что-то вродеconstexpr A c = Sum<a, b>();
или дополнительный шаг:constexpr A c = take<countLeadingZeros(a b)>(a b);
2. Подумайте о том, что
constexpr
делает аннотация для функции. Это позволяет выполнять функцию во время компиляции, но не заставляет ее. Это означает, что выoperator
также можете работать во время выполнения , что означает, что вы передаете значение времени выполненияcountLeadingZeros
, заставляя его также работать во время выполнения.3. Хорошо, спасибо тебе! Это был мой подход, но я хотел знать, можно ли это сделать без передачи a и b в параметр автоматического шаблона. Теперь мне все ясно, еще раз спасибо! 🙂 @Jarod42
4. Да, я знаю это @Timo . Но я подумал, что это обходной путь для этого. Спасибо! 🙂
5. @JeJo Не могли бы вы показать мне пример, потому что я его не понимаю.