[英]std::initializer_list and reference types
Can a std::initializer_list
contain reference types (both rvalue and lvalue)? std::initializer_list
可以包含引用类型(右值和左值)吗? Or does one have to use pointers or a reference wrapper (such as std::ref
)?还是必须使用指针或引用包装器(例如
std::ref
)?
EDIT:编辑:
Perhaps more clarification is due:也许需要更多说明:
I have a member variable, ::std::vector<std::function<void()> >
, into which I would like to forward a lambda object.我有一个成员变量
::std::vector<std::function<void()> >
,我想向其中转发一个 lambda 对象。 This would usually be accomplished with emplace_back
, but I wanted to do it in the constructor's initialization list.这通常用
emplace_back
来完成,但我想在构造函数的初始化列表中完成。 Alas, as I read, this would make forwarding impossible. las,正如我所读,这将使转发变得不可能。
Can a
std::initializer_list
contain reference types (both rvalue and lvalue)?std::initializer_list
包含引用类型(rvalue和lvalue)吗?
std::initializer_list<T>
doesn't hold references to its elements. std::initializer_list<T>
不包含对其元素的引用。 It uses copy-semantics by holding its values as const
objects: 它通过将其值保存为
const
对象来使用复制语义 :
18.9
Initializer List[support.initlist]
18.9
初始化列表[support.initlist]
An object of type
initializer_list<E>
provides access to an array of objects of typeconst E
.initializer_list<E>
类型的对象提供对const E
类型的对象数组的访问。
An initializer_list
of references will cause a compilation error because iternally pointers are used for iterators: 引用的
initializer_list
将导致编译错误,因为iternally指针用于迭代器:
#include <initializer_list>
int main()
{
int x;
std::initializer_list<int&> l = {x};
// In instantiation of 'class std::initializer_list<int&>':
// error: forming pointer to reference type 'int&'
// typedef const _E* iterator;
}
An initializer_list
also doesn't support move-semantics as const
objects cannot be moved from. initializer_list
也不支持move-semantics,因为const
对象无法移动。 Holding your objects in a std::reference_wrapper<T>
is the most viable solution if you wish to maintain reference-semantics. 如果您希望维护引用语义,那么将对象保存在
std::reference_wrapper<T>
是最可行的解决方案。
From http://www.cplusplus.com/reference/initializer_list/initializer_list/ 来自http://www.cplusplus.com/reference/initializer_list/initializer_list/
initializer_list objects are automatically constructed as if an array of elements of type T was allocated
initializer_list对象自动构造,就像分配了类型为T的元素数组一样
thus they can't be used with something like std::initializer_list<int&>
. 因此它们不能与
std::initializer_list<int&>
类的东西一起使用。 The reason is the same for which the following gives a compiler error 原因是相同的,以下给出了编译器错误
int& arr[20];
error: declaration of 'arr' as array of references
错误:将'arr'声明为引用数组
and that is dictated by the C++ standard: https://stackoverflow.com/a/1164306/1938163 这取决于C ++标准: https : //stackoverflow.com/a/1164306/1938163
As others mentioned, you cannot use std::initializer_list
with references.正如其他人提到的,您不能将
std::initializer_list
与引用一起使用。 You can use std::initializer_list<std::reference_wrapper<...>>
, but it will prevent your from passing rvalues as arguments to the constructor, because std::reference_wrapper
can only bind to lvalues.您可以使用
std::initializer_list<std::reference_wrapper<...>>
,但它会阻止您将右值作为参数传递给构造函数,因为std::reference_wrapper
只能绑定到左值。 In other words, the following will not compile:换句话说,以下不会编译:
YourContainerOfFunctions C{ [](){} };
This makes usage of std::initializer_list
in your case neither efficient nor convenient.这使得在您的情况下使用
std::initializer_list
既不高效也不方便。
I believe that is what you wanted to achieve:我相信这就是您想实现的目标:
class Foo {
std::vector<std::function<void()>> Functions;
public:
template <class... FuncTs>
Foo(FuncTs &&...Funcs) : Functions({std::forward<FuncTs>(Funcs)...}) {}
};
void foo(){};
int main() {
auto boo = []() {};
std::function<void()> moo = []() {};
Foo F{
foo, boo, // passed by reference, then copied
[]() {}, // moved, then copied
std::move(moo) // moved, then also moved
};
}
This requires at most one copy per argument, necessary because std::function
always make a copy of functor object which it is constructed from.每个参数最多需要一个副本,这是必要的,因为
std::function
总是复制构造它的仿函数对象。 An exception is construction of std::function
from std::function
of the same type一个例外是从相同类型的
std::function
::function 构造std::function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.