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.

+3


source to share


1 answer


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

      

+4


source







All Articles