Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 派生类中空初始化构造函数的constexpr_C++_C++11 - Fatal编程技术网

C++ 派生类中空初始化构造函数的constexpr

C++ 派生类中空初始化构造函数的constexpr,c++,c++11,C++,C++11,我有一些类似于下面的东西 class Base { public: explicit Base(int* i) noexcept { type = new int; *type = *i; }; constexpr Base(std::nullptr_t) : type(nullptr) { }; ~Base() { cout << "Destroying!" << endl; delete type; }; protected: int*

我有一些类似于下面的东西

class Base {
public:
    explicit Base(int* i) noexcept { type = new int; *type = *i; };
    constexpr Base(std::nullptr_t) : type(nullptr) { };
    ~Base() { cout << "Destroying!" << endl; delete type; };
protected:
    int* type;
};


class Derived : public Base {
public:
    explicit Derived(int* i) noexcept : Base(i) { };
    //constexpr Derived(std::nullptr_t) : type(nullptr) { };
    //constexpr Derived(std::nullptr_t) : Base(nullptr) { };
    ~Derived() { };
};
而且,在清理中,
handler1
handler2
都以某种方式进行管理

编辑:

Clang(3.4版)投诉:

error: constexpr constructor never produces a constant expression [-Winvalid-constexpr]
gcc(版本4.8[编辑:多个版本,未选中所有版本])在使用时不会抱怨

constexpr Derived(std::nullptr_t) : Base(nullptr) { };

事实上,
gcc
似乎实现了我想要实现的目标,但我对
constexpr
的理解还不够,无法知道哪个编译器做得对,以及如何修改问题。

常量表达式的类型必须是文本类型。事实上,“文字类型”分类单元的全部目的是“成为可以是常量表达式的事物”。见[expr.const]:

条件表达式
e
是一个核心常量表达式,除非按照抽象机器(1.9)的规则对
e
求值将求值以下表达式之一:

-对文本类的constexpr构造函数以外的函数的调用,即constexpr函数

因此,
constexpr
构造函数只允许您在文本类上生成常量表达式,否则,正如编译器告诉您的那样,它将“永远不会生成常量表达式”

文字类受[basic.types]的约束方式如下:

如果类型是:

-具有以下所有属性的类类型(第9条):

  • 它有一个小的析构函数
  • 它是聚合类型(8.5.1),或至少有一个
    constexpr
    构造函数或不是复制或移动构造函数的构造函数模板,以及
  • 它的所有非静态数据成员和基类都是非易失性文本类型
但是,从C++14开始(特别是从),构造函数还有另一个不相关的用途:它们允许静态初始化(从[basic.start.init]的意义上说):

对象
o
的常量初始值设定项是一个 常量表达式,但它也可以调用
o
及其子对象的
constexpr
构造函数,即使这些对象是非文本类类型[注:此类类可能具有非平凡的析构函数-结束注]

总而言之,从C++14开始,
constexpr
有两种用途:

  • C++11解释:“常量表达式”是与其值相同的表达式(即其计算没有副作用)
    constexpr
    变量只是其值的占位符,不用于其对象标识,通常期望常量表达式可以自由替换为其(编译时已知)值

  • C++14
    constexpr
    函数,包括构造函数:这些函数,包括构造函数,可以在静态初始化阶段调用,以恒定地初始化具有静态存储持续时间的变量。如果变量是对象,它们仍然保留其对象标识,可能需要动态销毁,但它们的初始化发生在任何动态初始化之前,不受排序的约束


  • 我得到的gcc错误(当使用
    constexpr-Derived a(nullptr);
    时)是不言自明的:
    'Derived'不是文字,因为:'Derived'有一个非平凡的析构函数。(这在
    Base
    中已经发生了。)@Jarod42很有趣,gcc 4.8.1-std=c++11我没有收到这个错误。@Jarod42但是我假设
    unique\u ptr
    没有一个简单的析构函数,并且使用了与我正在做的类似的东西,不是吗?@Jarod42@martin\u pr
    g++-4.7
    4.7.3版按照我的要求编译和运行(
    g++-4.7(Ubuntu/Linaro 4.7.3-12ubuntu1)4.7.3
    )我仍然不确定原因是什么,但更新版本的clang提供了有关错误的更多细节:
    注意:非文字类型“Base”不能用于constexpr派生的常量表达式(std::nullptr_t):Base(nullptr){};
    你比我先说一下:)可以找到对文字类型更详细的解释,是的,但我个人认为旧的解释更容易理解。因此,我为
    std::unique_ptr
    构造函数提供的
    constexpr
    没有意义?据我所知,没有,因为它包含一个指针和一个非平凡的析构函数。
    constexpr Derived(std::nullptr_t) : Base(nullptr) { };