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
- 它的所有非静态数据成员和基类都是非易失性文本类型
o
的常量初始值设定项是一个
常量表达式,但它也可以调用o
及其子对象的constexpr
构造函数,即使这些对象是非文本类类型[注:此类类可能具有非平凡的析构函数-结束注]
总而言之,从C++14开始,constexpr
有两种用途:
constexpr
变量只是其值的占位符,不用于其对象标识,通常期望常量表达式可以自由替换为其(编译时已知)值constexpr
函数,包括构造函数:这些函数,包括构造函数,可以在静态初始化阶段调用,以恒定地初始化具有静态存储持续时间的变量。如果变量是对象,它们仍然保留其对象标识,可能需要动态销毁,但它们的初始化发生在任何动态初始化之前,不受排序的约束我得到的gcc错误(当使用
constexpr-Derived a(nullptr);
时)是不言自明的:'Derived'不是文字,因为:'Derived'有一个非平凡的析构函数。(这在Base
中已经发生了。)@Jarod42很有趣,gcc 4.8.1-std=c++11我没有收到这个错误。@Jarod42但是我假设unique\u ptr
没有一个简单的析构函数,并且使用了与我正在做的类似的东西,不是吗?@Jarod42@martin\u prg++-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) { };