Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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_Clang_C++14_Constexpr - Fatal编程技术网

C++ 在constexpr中使用普通复制/移动可分配并集时发生冲突

C++ 在constexpr中使用普通复制/移动可分配并集时发生冲突,c++,c++11,clang,c++14,constexpr,C++,C++11,Clang,C++14,Constexpr,考虑到以下代码 struct S { constexpr S() = default; constexpr S(S const &) = default; constexpr S(S &) = default; constexpr S(S &&) = default; #if 1 S & operator = (S const &) = default; S & operator = (S &

考虑到以下代码

struct S
{
    constexpr S() = default;
    constexpr S(S const &) = default;
    constexpr S(S &) = default;
    constexpr S(S &&) = default;
#if 1
    S & operator = (S const &) = default;
    S & operator = (S &) = default;
    S & operator = (S &&) = default;
#else
    constexpr S & operator = (S const &) = default;
    constexpr S & operator = (S &) = default;
    constexpr S & operator = (S &&) = default;
#endif
    ~S() = default;
};

struct U
{

    union
    {
        S s;
    };

    constexpr U() : s{} { ; }

};

inline constexpr bool test()
{
    U v;
    U w;
    v = w;
    return true;
}

static_assert(test());
我发现有矛盾

我想在
constexpr
中使用
union
(或类似union的类)

版本
#如果1
给出错误(
错误:constexpr函数从不生成常量表达式
):

但是版本
#如果0
也会给出一个错误(
错误:复制赋值运算符的默认定义不是constexpr
):

以上所有内容适用于
clang3.7.0版本
,但较新版本的
clang3.8.0(主干253951)
没有说明
constepr S&operator=(S const&)=default(它允许编译这样的代码),但结果是一样的

对于简单的复制/移动构造函数,但用户提供的赋值运算符类似的代码(构造)编译起来很好

我认为问题(bug)在于用户声明的特殊函数,但它应该是合法的

另外,请看合同的最后一条和最后一条。在我看来,由于编译器对下一个定义的解释不同,设计得相当好的
变体在
constexpr
中变得毫无用处:

struct S {};
以及:

但在我看来,两者都是等价的(编译器认为第二个不是POD,但谁在乎呢?)

为什么空
struct
的默认赋值运算符不是
constexpr

更新:
删除析构函数声明会使问题消失。因此,即使是用户声明的(非用户提供的)析构函数也会使隐式定义的默认赋值运算符不被标记为
constexpr
,并且是非平凡的。这肯定是错误的,因为没有人告诉我这一点。

在开发过程中,我意识到
clang
联合部分和
libc++
部分测试非常差。gcc/clang同意
constepr
赋值是错误的,但当它未标记为
constexpr
时,他们不同意:
main.cpp:12:5: error: defaulted definition of copy assignment operator is not constexpr
    constexpr S & operator = (S const &) = default;
    ^
main.cpp:13:5: error: defaulted definition of copy assignment operator is not constexpr
    constexpr S & operator = (S &) = default;
    ^
main.cpp:14:5: error: defaulted definition of move assignment operator is not constexpr
    constexpr S & operator = (S &&) = default;
    ^
main.cpp:35:7: error: object of type 'U' cannot be assigned because its copy assignment operator is implicitly deleted
    v = w;
      ^
main.cpp:24:11: note: copy assignment operator of 'U' is implicitly deleted because field 's' has no copy assignment operator
        S s;
          ^
4 errors generated.
struct S {};
struct S
{
    constexpr S() = default;
    constexpr S(S const &) = default;
    constexpr S(S &) = default;
    constexpr S(S &&) = default;
    S & operator = (S const &) = default;
    S & operator = (S &) = default;
    S & operator = (S &&) = default;
    ~S() = default;
};