std::any for move-only template where static_assert inside copy-ctor equals compile error,但为什么呢?
std::any for move-only template where static_assert inside copy-ctor equals compile error, but why?
我不明白为什么只能移动的模板不能通过具有 static_assert
的复制函数扩展(如下面的代码)以便与 std::any
[= 一起使用19=]
#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
This overload only participates in overload resolution if ... std::is_copy_constructible_v<std::decay_t<ValueType>> is true.
据我所知,std::is_copy_constructible<MoveOnly>::value
给出 true 并且永远不会调用 copy-ctor。那么编译器怎么可能仍然抱怨 copy-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
,所以我们别无选择,具有 可用的复制构造函数以防万一 它可能需要被调用。
编辑: 解决评论中提到的问题:
Ok. So do I understand this correct: The copy-ctor gets created and static_assert is being fired because a simple pointer is pointing to the copy-ctor?
本质上,是的。一旦指针指向一个函数,该函数就必须存在,并且使该函数存在将触发它的代码生成,包括评估任何 static_assert()
中的任何内容。
您的理解中唯一有一点偏差的是指针的存在并不是为了它。它在那里是因为它很有可能被用来调用指向的函数。也许它会在 LTO 期间得到优化,但为时已晚; code-gen 到那时完成
我不明白为什么只能移动的模板不能通过具有 static_assert
的复制函数扩展(如下面的代码)以便与 std::any
[= 一起使用19=]
#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
This overload only participates in overload resolution if ... std::is_copy_constructible_v<std::decay_t<ValueType>> is true.
据我所知,std::is_copy_constructible<MoveOnly>::value
给出 true 并且永远不会调用 copy-ctor。那么编译器怎么可能仍然抱怨 copy-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
,所以我们别无选择,具有 可用的复制构造函数以防万一 它可能需要被调用。
编辑: 解决评论中提到的问题:
Ok. So do I understand this correct: The copy-ctor gets created and static_assert is being fired because a simple pointer is pointing to the copy-ctor?
本质上,是的。一旦指针指向一个函数,该函数就必须存在,并且使该函数存在将触发它的代码生成,包括评估任何 static_assert()
中的任何内容。
您的理解中唯一有一点偏差的是指针的存在并不是为了它。它在那里是因为它很有可能被用来调用指向的函数。也许它会在 LTO 期间得到优化,但为时已晚; code-gen 到那时完成