静态数据成员:它"const declaration / constexpr definition"起作用?
Static data member: "const declaration / constexpr definition" does it work?
以下一段代码试图提供一个 constexpr 属于类型 X 本身的 X 类型的静态数据成员。 在标准库(C++20(中,似乎有这样的例子 (至少(具有类"std::strong_ordering"及其少数静态 ConstexPR成员命名为"相等","更少","更大"和"等效"。 我想知道是否可以(以及如何(在没有编译器魔法的情况下实现这一目标。
直接声明(包括定义(确实如此 似乎不适用于任何编译器,也不是有效的C++。 话虽如此,后来又声明为"const" (在类之外(根据"constexpr"的定义似乎 与 GCC 一起工作,至少在某些情况下与 Clang 一起工作。
我的问题如下:
- 技巧是否由"常量声明"后跟 "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问题,它们是 相关但(在我看来(没有清楚地回答我的问题。
这个试图实现与我相同的目标,但似乎没有 提到"常量声明/constexpr 定义"技巧。一个类不能有自己的静态 constexpr 成员实例吗?
这个提到了"const 声明/constexpr 定义"技巧,但是 没有清楚地回答它是否有效的问题C++代码。静态常量声明,变量的constexpr定义,有效的c ++?
关于std::strong_ordering
的例子:C++标准本身声明这些静态数据成员是用const
声明的,并在类外部用inline constexpr
定义,所以这应该被认为是这种技术实际上在标准C++中工作的有力证据。例如,请参阅此处。
我在标准中找不到任何理由证明 Clang 只有在模板化时才拒绝这一点。似乎已经针对Clang提交了识别特定问题的错误,尽管维护者似乎尚未确认。
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- constexpr上下文中std::initializer_list的验证
- constexpr构造函数需要常量成员函数时出现问题
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- C++constexpr实现差异
- 添加静态constexpr成员是否会更改结构/类的内存映射
- 静态数据成员:它"const declaration / constexpr definition"起作用?