C++ 错误:使用删除的功能。为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26749505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: use of deleted function. Why?
提问by quant
I am trying to create a function that applies an arbitrary functor F
to every element of a provided tuple:
我正在尝试创建一个将任意函子应用于F
提供的元组的每个元素的函数:
#include <functional>
#include <tuple>
// apply a functor to every element of a tuple
namespace Detail {
template <std::size_t i, typename Tuple, typename F>
typename std::enable_if<i != std::tuple_size<Tuple>::value>::type
ForEachTupleImpl(Tuple& t, F& f)
{
f(std::get<i>(t));
ForEachTupleImpl<i+1>(t, f);
}
template <std::size_t i, typename Tuple, typename F>
typename std::enable_if<i == std::tuple_size<Tuple>::value>::type
ForEachTupleImpl(Tuple& t, F& f)
{
}
}
template <typename Tuple, typename F>
void ForEachTuple(Tuple& t, F& f)
{
Detail::ForEachTupleImpl<0>(t, f);
}
struct A
{
A() : a(0) {}
A(A& a) = delete;
A(const A& a) = delete;
int a;
};
int main()
{
// create a tuple of types and initialise them with zeros
using T = std::tuple<A, A, A>;
T t;
// creator a simple function object that increments the objects member
struct F
{
void operator()(A& a) const { a.a++; }
} f;
// if this works I should end up with a tuple of A's with members equal to 1
ForEachTuple(t, f);
return 0;
}
Live code example: http://ideone.com/b8nLCy
实时代码示例:http: //ideone.com/b8nLCy
I don't want to create copies of A
because it might be expensive (obviously in this example it is not) so I deleted the copy constructor. When I run the above program I get:
我不想创建 的副本,A
因为它可能很昂贵(在这个例子中显然不是)所以我删除了复制构造函数。当我运行上述程序时,我得到:
/usr/include/c++/4.8/tuple:134:25: error: use of deleted function ‘A::A(const A&)' : _M_head_impl(__h) { }
/usr/include/c++/4.8/tuple:134:25: error: use of deleted function ‘A::A(const A&)' : _M_head_impl(__h) { }
I know that the constructor is deleted (that was intentional) but what I don't understand is why it is trying to make copies of my struct. Why is this happening, and how can I achieve this without copying A
?
我知道构造函数被删除了(这是故意的),但我不明白的是为什么它试图复制我的结构。为什么会发生这种情况,我如何在不复制的情况下实现这一目标A
?
回答by Ben Voigt
This is the problem you're getting a "deleted constructor" error for:
这是您收到“已删除构造函数”错误的问题:
std::function<void(A)> f = [](A& a) { a.a++; };
You're trying to set up a std::function
that passes an A
by value. But A
, having no copy-constructor, can't be passed by value.
您正在尝试设置std::function
一个A
通过值传递的。但是A
,没有复制构造函数,不能按值传递。
Try matching the actual argument type more carefully:
尝试更仔细地匹配实际参数类型:
std::function<void(A&)> f = [](A& a) { a.a++; };
But since you aren't capturing variables, you can simply try
但是由于您没有捕获变量,您可以简单地尝试
void(*f)(A&) = [](A& a) { a.a++; };
You've also got a major problem with the base case of your template recursion: even if you get enable_if
working, which it seems not to be, you'll have an ambiguous call. I think you need to also disablethe main case.
您的模板递归的基本情况也有一个主要问题:即使您开始enable_if
工作(似乎并非如此),您也会遇到模棱两可的调用。我认为您还需要禁用主要案例。
回答by Dietmar Kühl
When instantiating std::function<void(A)>
a function with a signature taking an A
by value is instantiated. To synthesize this function definition a copy or a move of A
is needed. Since A
is non-copyable but not made movable, such a constructor doesn't exist.
当实例化std::function<void(A)>
一个带有A
按值的签名的函数时被实例化。要综合此函数定义,需要复制或移动A
。由于A
不可复制但不可移动,因此不存在这样的构造函数。
Of course, there is also this funny thing:
当然,也有这么搞笑的事情:
T t();
which declares a function return a T
by value requiring a copy. When calling ForEachTuple(t, f)
this function is referenced and instantiated. You may want to replace this declaration by one of
它声明一个函数返回一个T
需要副本的值。调用ForEachTuple(t, f)
此函数时会被引用和实例化。您可能希望用以下之一替换此声明
T t;
T t{};
(in the answer above I had only looked at the first problem I spotted).
(在上面的答案中,我只看了我发现的第一个问题)。