Skip to content

Defining static const member as const constinit outside class template while inside declaration contain constinit keyword valid or not #524

@ranaanoop

Description

@ranaanoop

Full name of submitter: Anoop Rana

Link to reflector thread (if any): https://stackoverflow.com/questions/78248691/static-data-member-of-template-class-type-constexpr-vs-const-constinit

Issue description:

Currently we can define a const static data member outside the class as constexpr as also noted in CWG 2800.

The problem is that all compilers seems to compile the following invalid(afaik) program, even though the declaration of ZeroVector inside the class template uses const constinit instead of just const. Demo

#include <array>

template<class T, std::size_t N>
    requires std::is_arithmetic_v<T> && (N >= 1)
class Vector 
{   
public:
    constexpr Vector() noexcept {}
    constexpr ~Vector() = default;
    //-----vvvvvvvvvvvvvvv-------------------->note this should be rejected but all 3 compilers accepts this
    static const constinit Vector ZeroVector;
};  
template<class T, std::size_t N> requires std::is_arithmetic_v<T> && (N >= 1)
const constinit Vector<T, N> Vector<T, N>::ZeroVector{};
int main()
{
    Vector<float, 7> boo = Vector<float, 7>::ZeroVector;
} 

The correct way to do this would be to remove the const constinit from the declaration that is inside the class and replace it with const. That is, the const constinit should only be in the definition outside the class as shown below:

#include <array>

template<class T, std::size_t N>
    requires std::is_arithmetic_v<T> && (N >= 1)
class Vector 
{   
public:
    constexpr Vector() noexcept {}
    constexpr ~Vector() = default;
    //-----vvvvv---------------------------NOTE ONLY THE CONST HERE
    static const Vector ZeroVector;
};  
template<class T, std::size_t N> requires std::is_arithmetic_v<T> && (N >= 1)
const constinit Vector<T, N> Vector<T, N>::ZeroVector{};
int main()
{
    Vector<float, 7> boo = Vector<float, 7>::ZeroVector;
}  

So, is snippet 1 supposed to be ill-formed or well-formed? Afaik snippet 1 is intended to be ill-formed and only snippet 2 is well-formed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions