Constrexpr constructor inherited from shared_ptr
I want to implement my own pointer (with a few helper methods) extended from 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) {
}
};
The problem is that the compiler gives me the following error for both constexpr constructors: A constexpr constructor never creates a constant expression
Please tell me how to fix this.
source to share
Constexpr constructor rules changed between C ++ 11 and C ++ 14; see DR1911 constexpr constructor with illiberal base class and this error .
The fix is ββto compile in C ++ 14 ( -std=c++14
) mode .
Language in C ++ 11 [dcl.constexpr] :
For a constexpr function, if there are no function argument values ββsuch that function substitution would call a constant expression (5.19), the program is ill-formed; no diagnostics required. For a constexpr constructor, if there are no argument values ββthat, after replacing the invocation function, the constructor call and the full expression in mem initializers will be a constant expression (including conversions), the program is ill-formed; no diagnostics required.
C ++ 11 shared_ptr
can have constructors constexpr
, but any class type inheriting from shared_ptr
or with an element shared_ptr
cannot, since shared_ptr
it is not a literal type (it has a destructor) and therefore cannot appear in a constant expression. For C ++ 14, this has been simplified:
For a non-symbolic, non-default constexpr function, or a non-default non-template that does not inherit a constexpr constructor, if there are no argument values, so that a function or constructor call may be an evaluated subexpression of the main constant expression (5.19), the program is ill-formed; no diagnostics required.
Unfortunately, this makes all constexpr constructors of non-literal types undefined; DR1911 fixed this by adding a sub-clause ( bold ):
For a non-symbolic, non-default constexpr function, or a non-default non-template that does not inherit a constexpr constructor if there are no argument values, so that a function or constructor call can be an evaluated subexpression (5.20), or, for a constructor, a constant initializer for some object (3.6.2),, the program is poorly formed; no diagnostics 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
source to share