这个问题似乎与an existing one有关,但我不明白"便携式解决方法"在the answer there中提供(涉及const auto this_ = this;
),而且我认为以下示例更容易理解。
我正在使用以下C ++ 17代码片段(live demo):
#include <iostream>
struct Test {
const char* name_{nullptr};
const Test* src_{nullptr};
constexpr Test(const char* name) noexcept
: name_{name}
{}
constexpr Test(const Test& src) noexcept
: src_{&src}
{
name_ = src_->name_;
src_ = nullptr;
}
};
template<char c>
void print_constexpr_char() {
std::cout << c << std::endl;
}
int main() {
constexpr const char* in = "x";
constexpr auto foo = Test{in};
constexpr auto bar = Test{foo};
std::cout << bar.name_ << std::endl;
print_constexpr_char<bar.name_[0]>();
return 0;
}
使用GCC 7.2进行编译失败,而Clang 5.0.0没有看到任何问题。 GCC错误基本上是
错误:&#39; bar&#39;的值不能用于常量表达式
注意:&#39; bar&#39;在其自己的初始化程序中使用
我意识到删除最后的print_constexpr_char
使代码编译后更加困惑,尽管它仍然包含GCC过去抱怨的行constexpr auto bar = Test{foo};
(&#34;在其自己的初始化程序中使用#34;。)
constexpr
变量中的最终状态之前,是否有一种有效的方法/解决方法在constexpr
构造函数中使用指针作为中间阶段?答案 0 :(得分:10)
GCC拒绝代码是正确的(但错误消息可能会使用一些工作)。除非该变量具有静态存储持续时间,否则不能在常量表达式中使用变量的地址。
foo
不是静态的。如果你将它移到main
之外,事情就会奏效。 Demo
下面标出的行是问题:
constexpr Test(const Test& src) noexcept
: src_{&src} <--- That
标准参考:( 强调我的)
[expr.const]
常量表达式是一个glvalue核心常量表达式,它引用一个允许的实体 常量表达式的结果(如下定义),或者值满足的prvalue核心常量表达式 以下约束:
(5.2) - 如果值是指针类型,它包含具有静态存储持续时间的对象的地址, 地址超过此类对象的结尾(8.7),函数的地址或空指针值