gpt4 book ai didi

c++ - Clang 和 GCC vs MSVC 和 ICC : Is a static_assert in the copy/move constructor required to work, 如果复制/移动省略也可以应用?

转载 作者:IT老高 更新时间:2023-10-28 13:01:37 26 4
gpt4 key购买 nike

我的模板结构的移动构造函数中有一个 static_assert。编译器是否需要考虑这个 static_assert,即使复制省略是可能的?

这是精简的场景:

#include <type_traits>

template<typename T>
struct X
{
X(X&&) { static_assert(std::is_same<void, T>::value, "Intentional Failure"); }
};

auto impl() -> X<int>;
auto test() -> decltype(impl())
{
return impl();
}

int main()
{
test();
}

GCC 和 Clang 同意评估 static_assert 并且编译失败。
另一方面,MSCV 和 ICC 可以很好地编译代码。

有趣的是,当我删除 move 构造函数的定义并像这样声明它时:

template<typename T>
struct X
{
X(X&&);
};

GCC 和 Clang 现在也编译代码。因此,所有编译器似乎都同意移动构造函数的定义与复制省略无关。

问题:
如果复制/移动构造函数中存在 static_assert,即使复制/移动省略是可能的,标准是否要求对其进行评估?

最佳答案

以下内容应该会有所帮助。

您不必使用类型推导来说明问题。即使是更简单的例子也有同样的问题:

#include <type_traits>

template <typename T>
struct X
{
X() {}
X(X&&) { static_assert(std::is_same<void, T>::value, "failed"); }
};

int main()
{
X<int> x = X<int>();
}

Clang 和 GCC 不会编译它。 MSVC 编译执行良好。

这表明问题与使用 odr 以及何时实例化成员函数的定义有关。

14.7.1 [temp.inst] 第 2 段 说“[...] 当在需要成员定义存在的上下文中引用特化时,成员的特化被隐式实例化"

3.2 [basic.def.odr] 第 3 段 说(在注释中)“[...] 选择用于复制或移动类类型对象的构造函数是 odr 使用的,即使通话实际上被实现省略了”

3.2 [basic.def.odr] 第 4 段 说:“每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的一个定义;不需要诊断。 "

Ergo:应该实例化特化,并且断言已经触发。

关于c++ - Clang 和 GCC vs MSVC 和 ICC : Is a static_assert in the copy/move constructor required to work, 如果复制/移动省略也可以应用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371571/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com