Создайте переменную, используя этот указатель и аргументы метода во время компиляции, и используйте эту переменную в качестве аргумента метода constexpr

#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 Не могли бы вы показать мне пример, потому что я его не понимаю.