【问题标题】:constrexpr constructor inherited from shared_ptr继承自 shared_ptr 的 constrexpr 构造函数
【发布时间】:2015-07-23 09:27:02
【问题描述】:

我想实现我自己的从 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) {
    }
};

问题是编译器为两个 constexpr 构造函数都给了我以下错误: constexpr 构造函数永远不会产生常量表达式

请告诉我如何解决它。

【问题讨论】:

标签: c++ memory constructor shared-ptr constexpr


【解决方案1】:

关于 constexpr 构造函数的规则在 C++11 和 C++14 之间发生了变化;见DR1911 constexpr constructor with non-literal base classthis bug

修复方法是在 C++14 模式下编译 (-std=c++14)。

C++11 中的语言[dcl.constexpr]

对于 constexpr 函数,如果不存在函数参数值使得函数调用替换会产生一个常量表达式 (5.19),则程序是非良构的;无需诊断。对于 constexpr 构造函数,如果不存在参数值,那么在函数调用替换之后,每个 mem-initializers 中的构造函数调用和完整表达式将是一个常量表达式(包括转换),程序格式错误;无需诊断。

在 C++11 下,shared_ptr 可以具有 constexpr 构造函数,但任何继承自 shared_ptr 或具有 shared_ptr 成员的类类型都不能,因为 shared_ptr 不是文字类型(它具有析构函数),因此不能出现在常量表达式中。对于 C++14,这被简化为:

对于非模板、非默认的 constexpr 函数或非模板、非默认、非继承的 constexpr 构造函数,如果不存在参数值,则函数或构造函数的调用可能是核心常量表达式(5.19),程序格式错误;无需诊断。

不幸的是,这使得 all 非文字类型的 constexpr 构造函数未定义行为; DR1911 通过添加子条款(粗体下面)解决了这个问题:

对于非模板、非默认的 constexpr 函数或非模板、非默认、非继承的 constexpr 构造函数,如果不存在参数值,则函数或构造函数的调用可能是核心常量表达式 (5.20),或者,对于构造函数,某个对象的常量初始化器 (3.6.2), 程序格式错误;无需诊断。

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

【讨论】:

  • 我不明白这是如何应用的(第二,强调的段落是 C++14 的新内容还是在 C++14 中被删除)?由于两个使用的shared_ptr 构造函数都是constexpr,为什么调用可以是“核心常量表达式的评估子表达式”?那么具有该属性的构造函数是什么?
  • “为什么不能”,而不是“为什么可以”。
  • @Cheersandhth.-Alf 谢谢,我对 DR1911 的文字感到困惑。 C++11 允许非文字类型的 constexpr 构造函数,但不允许继承自或包含非文字类型的类型; C++14 实际上使所有非文字类型的 constexpr 构造函数都成为 UB,但 DR 修复了这个问题。
  • @ecatmur 抱歉,UB 是什么?
  • @Peregrin UB 是 undefined behavior
猜你喜欢
  • 1970-01-01
  • 2013-06-01
  • 2023-04-03
  • 2015-06-21
  • 2023-03-07
  • 2013-03-21
相关资源
最近更新 更多