constrexpr 构造函数继承自 shared_ptr
constrexpr constructor inherited from shared_ptr
我想实现我自己的从 shared_ptr.
扩展而来的指针(使用一些辅助方法)
class Event;
class EventPtr : public std::shared_ptr<Event> {
public:
constexpr EventPtr()
: std::shared_ptr<Event>() {
}
constexpr EventPtr(std::nullptr_t p)
: std::shared_ptr<Event>(p) {
}
explicit EventPtr(Event* ptr)
: std::shared_ptr<Event>(ptr) {
}
};
问题是编译器为我提供了以下两个 constexpr 构造函数的错误:
constexpr 构造函数从不生成常量表达式
请告诉我如何解决它。
constexpr 构造函数的规则在 C++11 和 C++14 之间发生了变化;参见 DR1911 constexpr constructor with non-literal base class and this bug。
修复是在 C++14 模式下编译 (-std=c++14
)。
C++11 语言[dcl.constexpr]:
For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, every
constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.
在 C++11 下,shared_ptr
可以有 constexpr
构造函数,但是任何继承自 shared_ptr
或具有 shared_ptr
成员的 class 类型都不能,因为 shared_ptr
不是文字类型(它有析构函数)所以不能出现在常量表达式中。对于 C++14,这被简化为:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.
不幸的是,这使得 all constexpr 非文字类型的构造函数未定义行为; DR1911 通过添加子条款(下面的 粗体 )解决了这个问题:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.20), or, for a constructor, a constant initializer for some object (3.6.2), the program is ill-formed; no diagnostic required.
struct X { ~X() {} constexpr X() {} }; // OK in C++11, UB in C++14, OK since DR1911
struct Y : X { constexpr Y() : X() {} }; // UB in C++11, UB in C++14, OK since DR1911
我想实现我自己的从 shared_ptr.
扩展而来的指针(使用一些辅助方法)class Event;
class EventPtr : public std::shared_ptr<Event> {
public:
constexpr EventPtr()
: std::shared_ptr<Event>() {
}
constexpr EventPtr(std::nullptr_t p)
: std::shared_ptr<Event>(p) {
}
explicit EventPtr(Event* ptr)
: std::shared_ptr<Event>(ptr) {
}
};
问题是编译器为我提供了以下两个 constexpr 构造函数的错误: constexpr 构造函数从不生成常量表达式
请告诉我如何解决它。
constexpr 构造函数的规则在 C++11 和 C++14 之间发生了变化;参见 DR1911 constexpr constructor with non-literal base class and this bug。
修复是在 C++14 模式下编译 (-std=c++14
)。
C++11 语言[dcl.constexpr]:
For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.
在 C++11 下,shared_ptr
可以有 constexpr
构造函数,但是任何继承自 shared_ptr
或具有 shared_ptr
成员的 class 类型都不能,因为 shared_ptr
不是文字类型(它有析构函数)所以不能出现在常量表达式中。对于 C++14,这被简化为:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.
不幸的是,这使得 all constexpr 非文字类型的构造函数未定义行为; DR1911 通过添加子条款(下面的 粗体 )解决了这个问题:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.20), or, for a constructor, a constant initializer for some object (3.6.2), the program is ill-formed; no diagnostic required.
struct X { ~X() {} constexpr X() {} }; // OK in C++11, UB in C++14, OK since DR1911
struct Y : X { constexpr Y() : X() {} }; // UB in C++11, UB in C++14, OK since DR1911