std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
std::any for move-only template where static_assert inside copy-ctor equals compile error, but why?
我不明白为什么只有移动模板不能由具有static_assert
的复制ctor扩展(如下面的代码(以便与std::any
一起使用
#include <any>
#include <cassert>
namespace detail{
template<typename T=int>
struct MoveOnly
{
MoveOnly() = default;
MoveOnly(MoveOnly const&) {static_assert(sizeof(T)!=sizeof(T),"");}
MoveOnly(MoveOnly &&) = default;
MoveOnly &operator=(MoveOnly const&) {static_assert(sizeof(T)!=sizeof(T),"");}
MoveOnly &operator=(MoveOnly &&) = default;
};
}
using MoveOnly = detail::MoveOnly<>;
static_assert(std::is_copy_constructible<MoveOnly>::value,"");
int main() {
MoveOnly a;
//std::any any(std::move(a)); //<- compile error
return 0;
}
在std::any::any中,它表示ctor#4
此重载仅在。。。std::is_copy_constructible_v<std::decay_t<值类型>gt;是真的。
据我所见,std::is_copy_constructible<MoveOnly>::value
给出true,并且从未调用复制ctor。那么,编译器怎么可能仍然抱怨复制器中的static_assert
呢?
考虑以下情况:
foo.h:
void foo(const std::any& v);
foo.cpp:
void foo(const std::any& v) {
std::any tmp = v;
}
main.cpp:
#include "foo.h"
int main() {
MoveOnly a;
std::any any(std::move(a));
foo(any);
return 0;
}
在main.cpp
内部,无法知道foo()
是否会复制v
,因此我们别无选择,有作为可用的复制构造函数,以防可能需要调用它。
编辑:要解决评论中提到的问题:
好的。那么,我是否正确理解这一点:创建了复制ctor,并且由于一个简单的指针指向复制ctor而触发了static_assert?
本质上,是的。一旦指针引用了一个函数,该函数就必须存在,并且使该函数存在将触发它的代码生成,包括评估其中的任何static_assert()
。
在你的理解中,唯一有点偏离的是,指针的存在并不是为了它。它之所以存在,是因为它确实有可能被用来调用指向的函数。也许它会在LTO期间得到优化,但为时已晚;代码生成在之前完成
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 编译依赖于 QTCore 库的 WASM
- std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
- CMake:如何在Visual Studio环境中将依赖于模式的编译标志传递给nvcc
- 使用程序集嵌入数据时"Undefined reference"错误,使用适用于窗口的 mingw-w64 编译(COFF 而不是 ELF)
- 应用于整型类型的编译时优化 'std::isfinite()'
- 在 NDK 上编译两个带有 gradle 的项目,其中一个依赖于另一个的二进制文件
- 如何编译适用于较旧 Linux 发行版的二进制文件
- g++编译存在于另一个目录中的源文件
- 如何将assimp(assert importer)交叉编译到像ps4或XBox1这样的平台
- 链接器是否存在于所有编译的编程语言中
- C++使用可变模板编译特定于时间的函数
- 使用Android NDK编译Boost时assert.h冲突
- 子类中的这种变化是否需要重新编译依赖于超类的代码?
- ASSERT也适用于发布模式
- CppUnit期望Assert Throw异常编译时发出警告C4127
- 用于检查 R 函数是否依赖于 C/C++ 编译代码的函数
- 如果包括"assert.h"的每个文件都需要很长的编译时间吗?
- 当试图让const_iterator查找元素是否存在于集合中时,得到编译错误