【发布时间】:2016-08-25 11:14:38
【问题描述】:
如果有人能给我一个关于如何测试函子的琐碎复制能力的提示,我将不胜感激(打算使用 lambda)。正如this question 中所解释的,lambda 是否可以简单地复制是由实现定义的。例如,对于本问题末尾显示的代码 gcc (5.4) 和 msvc (2015) 都触发断言,这些断言不是可简单复制分配的。
我希望这些类型的 lambda 表达式由 struct 表示,保持 this 指针并拥有每个捕获值的副本(如果有)。因此,它们似乎都可以轻松复制 - 至少对于捕获的值可以轻松复制的情况。
驱动这个问题的真正用例是我正在使用一个回调(std::function 的简约版本,它不分配并且适用于非常简单的仿函数),它保持一个固定的缓冲区,它在其中复制构造(就地) 通过函子。然后我希望能够复制/分配这些回调,但为了使其工作(开箱即用)这些固定缓冲区的简单内存复制应该等同于应对/分配保存在其中的函子。
所以我有两个问题:
-
想象一下,在下面的
test_functor()中,我做new放置,例如喜欢new (&buffer) F(functor)对于下面显示的那种 lambda,只使用
memcopy这个缓冲区是否安全?我希望这应该是这样,因为对于所有情况,只有this指针被捕获或被捕获的值是可简单复制的,但如果有人能证实这一点,那就太好了。 如何测试简单复制保存仿函数的内存是否等同于复制仿函数?如果第一个问题的答案是肯定的,那么
std::is_trivially_copy_assignable不是正确答案。
#include <type_traits>
template <typename F>
void test_functor(const F& functor)
{
static_assert(std::is_trivially_destructible<F>::value,
"Functor not trivially destructible");
static_assert(std::is_trivially_copy_constructible<F>::value,
"Functor not trivially copy constructible");
static_assert(std::is_trivially_copy_assignable<F>::value,
"Functor not trivially copy assignable");
}
struct A
{
void test() { test_functor([this]() { }); }
};
struct B
{
void test() { test_functor([this](int v) { value = v; }); }
int value;
};
struct C
{
void test(int v) { test_functor([=]() { value = v; }); }
int value;
};
int main()
{
A a;
B b;
C c;
a.test();
b.test();
c.test(1);
return 0;
}
【问题讨论】:
-
您应该使用
is_trivially_copyable,而不是is_trivially_meow_constructible或is_trivially_meow_assignable。 Lambda 永远不会被简单地复制(或移动)赋值,因为它们的复制赋值运算符已被删除;这并不一定会阻止它们被简单地复制。 -
@T.C. - 你能在答案部分发表你的评论吗?我想将其标记为答案,因为您一针见血。我不知道 lambdas 的复制分配被删除了。确实
is_trivially_copyable正在通过。谢谢。