Статический член данных типа класса шаблона: constexpr против const constinitC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Статический член данных типа класса шаблона: constexpr против const constinit

Сообщение Anonymous »

У меня есть класс с тремя статическими переменными-членами:

Код: Выделить всё

#include 
#include 
#include 

struct VectorUnitIndexInitTag {};

struct VectorFillInitTag {};

template requires std::is_arithmetic_v && (N >= 1)
class Vector
{
public:

static constexpr std::size_t Dimension = N;

using iterator          = typename std::array::iterator;
using const_iterator    = typename std::array::const_iterator;

constexpr Vector() noexcept : Elements{} {}

private:

constexpr Vector(VectorUnitIndexInitTag, size_t Index) : Vector()
{
Elements[Index] = static_cast(1);
}

constexpr Vector(VectorFillInitTag, T Value) : Vector()
{
std::ranges::copy(std::ranges::repeat_view(Value, Dimension), begin());
}

public:

constexpr ~Vector() = default;

inline constexpr iterator begin() noexcept
{
return Elements.begin();
}

inline constexpr iterator end() noexcept
{
return Elements.end();
}

static constexpr Vector ZeroVector{};

template requires (I < N)
static constexpr Vector UnitVector{ VectorUnitIndexInitTag{}, I };

static constexpr Vector OneVector{ VectorFillInitTag{}, 1 };

private:

std::array Elements;

};

int main()
{
Vector boo = Vector::ZeroVector;
Vector boo2 = Vector::UnitVector;
Vector boo3 = Vector::OneVector;
}
Приведенное выше не удается скомпилировать в обозревателе компилятора с MSVC и Clang (магистраль) с флагами компилятора C++23, но оно компилируется в GCC (магистраль) с флагами компилятора C++23.
Clang выдает следующую ошибку:

Код: Выделить всё

:47:29: error: constexpr variable cannot have non-literal type 'const Vector'
47 |     static constexpr Vector ZeroVector{};
|                             ^
:73:28: note: in instantiation of template class 'Vector' requested here
73 |     Vector boo = Vector::ZeroVector;
|                            ^
:47:29: note: incomplete type 'const Vector' is not a literal type
47 |     static constexpr Vector ZeroVector{};
|                             ^
:10:7: note: definition of 'Vector' is not complete until the closing '}'
10 | class Vector
|       ^
:50:29: error: constexpr variable cannot have non-literal type 'const Vector'
50 |     static constexpr Vector UnitVector{ VectorUnitIndexInitTag{}, I };
|                             ^
:52:29: error: constexpr variable cannot have non-literal type 'const Vector'
52 | static constexpr Vector OneVector{ VectorFillInitTag{}, 1 };
|                         ^
3 errors generated.
Compiler returned: 1
MSVC выдает следующую ошибку:

Код: Выделить всё

(47): error C2027: use of undefined type 'Vector'
(10): note: see declaration of 'Vector'
(47): note: the template instantiation context (the oldest one first) is
(73): note: see reference to class template instantiation 'Vector' being compiled
(52): error C2027: use of undefined type 'Vector'
(10): note: see declaration of 'Vector'
Compiler returned: 2
Когда я меняю constexpr на const constinit для трех статических переменных-членов, это компилируется, когда определения перемещаются за пределы класса следующим образом:

Код: Выделить всё

template requires std::is_arithmetic_v && (N >= 1)
const constinit Vector Vector::ZeroVector{};

template requires std::is_arithmetic_v && (N >= 1)
template requires (I < N)
const constinit Vector Vector::UnitVector{ VectorUnitIndexInitTag{}, I };

template requires std::is_arithmetic_v && (N >= 1)
const constinit Vector Vector::OneVector{ VectorFillInitTag{}, 1 };
Так почему constexpr компилируется только в GCC, а const constinit компилируется во всех трех основных компиляторах?

Подробнее здесь: https://stackoverflow.com/questions/782 ... -constinit
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»