Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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++ 您是否可以从std::optional<;T>;其中T有非平凡构造函数?_C++_Webkit_C++17_Optional - Fatal编程技术网

C++ 您是否可以从std::optional<;T>;其中T有非平凡构造函数?

C++ 您是否可以从std::optional<;T>;其中T有非平凡构造函数?,c++,webkit,c++17,optional,C++,Webkit,C++17,Optional,我试图用叮当声编译WebKit,我之所以这么做,主要是因为以下模式: #include <iostream> #include <optional> struct X { X() = default; X(const X& other) { } }; struct Y { std::optional<X> x;; }; int main() { Y foo; Y bar(std::move(foo)); }

我试图用叮当声编译WebKit,我之所以这么做,主要是因为以下模式:

#include <iostream>
#include <optional>

struct X {
    X() = default;
    X(const X& other) { }
};

struct Y {
    std::optional<X> x;;
};

int main() {
    Y foo;
    Y bar(std::move(foo));
}

这是有效的C++,还是WebKIT损坏,CLAN合法拒绝这个代码?

< P>考虑这个类:

struct X
{
    X(int);
    X(X&&) = delete;

    // does this need to invoke the move constructor??
    X() : X(X(0)) { }
};
根据gcc,答案是否定的:这将直接委托给
X(int)
。根据clang的说法,答案是肯定的,但编译失败:


此类型已隐式删除了复制和移动构造函数,这是因为具有不可复制构造的成员的联合。因此,如果这个委托构造函数必须调用隐式复制构造函数(如clang所认为的),那么这是格式错误的。如果不必这样做,只需调用一个或另一个委托构造函数,那么这个调用就可以了

Y{}
已经是临时的,所以
std::move
是多余的。@Jarod42我想OP使用它是为了避免复制省略。@Jarod42经过编辑,只是为了让示例更清楚一点。我在godbolt.org上试用过,在我测试过的所有编译器(最新的MSVC、gcc和clang)中都编译得很好。不确定它使用的是什么libstdc++版本(也适用于libc++),所以它可能是8.1.1(或在clang&8.1.1组合中)中的一些“bug”。@Dan hm ok我尝试了clanghead和clang6.0.1与7.3.1和8.1.1的GCC库。我想我还需要设置一个Ubuntu在那里进行测试。所以根据这个(很棒!)的分析,在WebKit中以这种特殊的方式使用std::optional应该被认为是一个bug,或者在libstdc++中实现std::optional应该被认为是一个bug?在任何一种情况下,我都将通过降级到旧版本的libstdc++来解决这个问题,但我可能会让WebKit开发人员知道是否是前者。最近在core reflector上讨论了这个确切的示例—请参阅标题为“强制副本省略与ctor委派”的线程。
struct X
{
    X(int);
    X(X&&) = delete;

    // does this need to invoke the move constructor??
    X() : X(X(0)) { }
};
<source>:55:15: error: call to deleted constructor of 'X'    
        X() : X(X(0)) { }   
              ^ ~~~~    
<source>:52:9: note: 'X' has been explicitly marked deleted here    
        X(X&&) = delete;   
        ^
  constexpr
  _Optional_payload(bool __engaged, _Optional_payload&& __other)
  : _Optional_payload(__engaged
          ? _Optional_payload(__ctor_tag<bool>{},
                      std::move(__other._M_payload))
          : _Optional_payload(__ctor_tag<void>{}))
  { }