constexpr构造函数不能在constexpr构造函数中使用

Lær*_*rne 0 c++ constructor unique-ptr constexpr c++11

我想unique_ptr用一个特殊的析构函数重新定义.因此,我使用下面的代码,我试图模仿一些构造函数unique_ptr.不幸的是,constexpr构造者拒绝构建,我不知道为什么.

class job_ptr : public unique_ptr<Job>
{
public:
    constexpr job_ptr()
        : unique_ptr<Job>(), sequencer( nullptr ) {}
    constexpr job_ptr( nullptr_t )
        : unique_ptr<Job>( nullptr ), sequencer( nullptr ) {}
private:
    FIFOSequencer* sequencer;
};
Run Code Online (Sandbox Code Playgroud)

初始化列表中的两个构造函数都被声明constexpr,但是clang++考虑constexpr constructor never produces a constant expression因为non-literal type 'unique_ptr<Job>' cannot be used in a constant expression.这意味着什么? constexpr构造函数不能在constexpr构造函数中使用?

感谢您的任何帮助.

Joh*_*han 5

Constexpr构造函数是可能的,但要求非常严格.正如@dyp所说,你面临的主要问题是,因为std::unique_ptr没有琐碎的析构函数,因此不是一个 LiteralType.

如果您尝试使用intunder g ++:

class int_ptr : public std::unique_ptr<int>
{
public:
    constexpr int_ptr()
        : std::unique_ptr<int>(), sequencer( nullptr ) {}
    constexpr int_ptr( nullptr_t )
        : std::unique_ptr<int>( nullptr ), sequencer( nullptr ) {}
private:
    int* sequencer;
};

constexpr int_ptr ptr;
Run Code Online (Sandbox Code Playgroud)

您有一个非常明确的错误消息:

unique_ptr.cpp:40:20: error: the type ‘const int_ptr’ of constexpr variable ‘ptr’ is not literal
  constexpr int_ptr ptr;
                    ^
unique_ptr.cpp:27:7: note: ‘int_ptr’ is not literal because:
 class int_ptr : public std::unique_ptr<int>
       ^
unique_ptr.cpp:27:7: note:   ‘int_ptr’ has a non-trivial destructor
Run Code Online (Sandbox Code Playgroud)

在您的情况下,如评论中所建议的,使用自定义删除器.STL容器不太适合继承.

这是自定义删除器的示例:

#include <memory>
#include <iostream>

template <typename T>
struct Deleter
{
    void operator()(T* t)
    {
        std::cout << "Deleter::oerator(): " << t << std::endl;
        delete t;
    }
};

struct A 
{
    A() 
    {
        std::cout << "A::A()" << std::endl;
    }

    ~A() 
    {
        std::cout << "A::~A()" << std::endl;
    }
};

int main(int argc, char const *argv[])
{
    std::unique_ptr<A, Deleter<A>> ptr(new A);


    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它输出:

A::A()
Deleter::oerator(): 0x600010480
A::~A()
Run Code Online (Sandbox Code Playgroud)

(现场直播