GCC和Clang对constexpr构造函数的不同行为

Ziz*_*Tai 14 c++ c++11

对于这个结构:

struct Wrapper {
    int value;

    constexpr explicit Wrapper(int v) noexcept : value(v) {}
    Wrapper(const Wrapper& that) noexcept : value(that.value) {}
};
Run Code Online (Sandbox Code Playgroud)

而这个功能:

constexpr Wrapper makeWrapper(int v)
{
    return Wrapper(v);
}
Run Code Online (Sandbox Code Playgroud)

以下代码无法为Clang(Apple LLVM版本7.3.0)编译,但是对于GCC(4.9+)编译良好,两者都具有-Wall -Wextra -Werror -pedantic-errors:

constexpr auto x = makeWrapper(123);
Run Code Online (Sandbox Code Playgroud)

Clang抱怨说"非constexpr构造函数'Wrapper'不能用于常量表达式." 哪个编译器是对的?

Die*_*ühl 14

虽然返回时的复制或移动WrappermakeWrapper()可被省略,则需要用C++ 14存在.现有的复制构造函数是非的constexpr,它的存在禁止创建隐式移动构造函数.结果我觉得clang是对的:你需要制作一个复制构造函数constexpr.

请注意,使用C++ 17代码可能会变得正确:有一个建议在某些情况下强制执行copy-elision:P0135r0.然而,似乎这种变化尚未落入工作文件中.它可能会在本周登陆(感谢@NicolBolas指出它不在那里).我没有在邮件中看到更新的论文.

  • 我知道你在C++ ISO委员会(WG21),请,我想问:*"我们什么时候说一个函数或构造函数是****可访问****?"* - 因为其中一个要求对于copy-elision来说,"可以访问".阅读[this](http://eel.is/c++draft/class.copy#32)段落的结尾 (2认同)
  • @ZizhengTai:即使事情已经在论文中,我们也不能依赖C++ 17.然而,由于变化没有落地,没有纸张存在,甚至可能没有讨论.查看核心工作组的工作时间表,有一个更新(D0135r1;"D"表示它是一篇迟到的文章,由于某种原因没有进入邮件)并计划对此进行查看一周由Core.实际上,今天讨论了它,讨论以"准备周五投票"结束,所以看起来不错...... (2认同)