以下代码尝试提供属于 X 类型本身的 X 类型的 constexpr 静态数据成员。在标准库(C++20)中,似乎有这样的例子,(至少)类“std::strong_ordering”和它的少数静态constexpr成员命名为“equal”、“less”、“greater”和“相等的'。我想知道是否(以及如何)在没有编译器魔法的情况下实现这一点。
直接声明(包括定义)似乎不适用于任何编译器,也不是有效的 C++。话虽如此,随后(在类之外)定义为“constexpr”的声明为“const”似乎适用于 GCC,至少在某些情况下适用于 Clang。
我的问题如下:
- 由“const 声明”和“constexpr 定义”组成的技巧是否形成了有效的 C++ 代码,该代码实际上在 X 类本身内部提供了 X 类型的有效静态 constexpr 数据成员?
- 非模板版本(类型 Foo)使用 GCC 和 Clang 编译,而模板版本(类型 Bar<0>)仅使用 GCC 编译。是否有任何规则可以使非模板版本有效的 C++ 代码和模板成为无效的 C++ 代码?
- Clang 产生的错误可以被认为是编译器错误吗?
源代码(C++17):
// With this non template struct,
// It compiles successfully with GCC and Clang.
struct Foo
{
// A data member.
int val;
// A static data member.
// It is declared here as 'const'
// and defined below as 'constexpr'.
static Foo const instance;
// A constexpr constructor.
constexpr Foo(int value) noexcept : val{ value } {}
};
// With this non template struct,
// It compiles successfully with GCC
// but it generates an error with Clang.
template<int N>
struct Bar
{
// A data member.
int val;
// A static data member.
// It is declared here as 'const'
// and defined below as 'constexpr'.
static Bar const instance;
// A constexpr constructor.
constexpr Bar(int value) noexcept : val{ value } {}
};
// Definition of the static
// data member of the struct Foo.
// Note that it is defined here as 'constexpr'
// while it was declared above only as 'const'.
constexpr Foo const Foo::instance{32};
// Definition of the static data
// member of the template struct Foo.
// Note that it is defined here as 'constexpr'
// while it was declared above only as 'const'.
template<int N>
constexpr Bar<N> const Bar<N>::instance{32};
// The main function.
int main()
{
// Init a constexpr const reference to
// the static data member object of type Foo.
constexpr Foo const& foo{ Foo::instance };
// Init a constexpr const reference to
// the static data member object of type Bar<0>.
constexpr Bar<0> const& bar{ Bar<0>::instance };
// This compile time check
// works fine with GCC and Clang.
static_assert(foo.val == 32);
// This compile time check works fine with GCC
// but generates a compilation error with Clang.
static_assert(bar.val == 32);
// Return zero.
return 0;
};
以前的 StackOverflow 相关问题:
我引用了两个相关的 StackOverflow 问题,但(在我看来)并没有明确回答我的问题。
这个试图实现与我相同的目标,但似乎没有提到“const 声明/ constexpr 定义”技巧。一个类不能有自己的静态 constexpr 成员实例吗?
这个提到了“const 声明/constexpr 定义”技巧,但没有明确回答它是否是有效的 C++ 代码的问题。静态 const 声明,变量的 constexpr 定义,有效的 C++?