std::initializer_list
能否包含引用类型(rvalue和lvalue)?还是必须使用指针或引用包装器(例如std::ref
)?
编辑:
也许需要更多的解释:
我有一个成员变量,类型为::std::vector<std::function<void()> >
,我想将lambda对象转发到其中。这通常可以使用emplace_back
来完成,但我想在构造函数的初始化列表中完成它。然而,据我所读,这会使转发变得不可能。
std::initializer_list
能否包含引用类型(rvalue和lvalue)?还是必须使用指针或引用包装器(例如std::ref
)?
编辑:
也许需要更多的解释:
我有一个成员变量,类型为::std::vector<std::function<void()> >
,我想将lambda对象转发到其中。这通常可以使用emplace_back
来完成,但我想在构造函数的初始化列表中完成它。然而,据我所读,这会使转发变得不可能。
std::initializer_list<T>
装载的元素不包含引用类型(无论是右值引用还是左值引用)。它使用拷贝语义,将其值以const
对象的形式储存:
18.9
Initializer List[support.initlist]
类型为
initializer_list<E>
的对象提供对一组const E
对象的访问。如果使用引用类型的
initializer_list
将会导致编译错误,因为迭代器内部使用指针实现:
#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;
}
initializer_list
不支持移动语义,因为 const
对象不可移动。如果您希望保持引用语义,则在 std::reference_wrapper<T>
中保存对象是最可行的解决方案。
const &&
。 - user1095108std::move()
并不能实现移动,它只是将其转换为右值。当一个构造函数采用非const rvalue引用 (X&&)
时,才真正地发生移动操作,而移动一个const
对象在某些情况下实际上会创建一个副本,在其他情况下则会导致编译错误。 - David Ginitializer_list对象会自动构造一个类型为T的元素数组,因此它们不能与像
std::initializer_list<int&>
这样的内容一起使用。原因是下面的代码也会产生编译错误。
int& arr[20];
错误: 将“arr”声明为引用数组
这是由C++标准所规定的: https://dev59.com/QnM_5IYBdhLWcg3w8H82#1164306
正如其他人所提到的,您不能在引用中使用std::initializer_list
。您可以使用std::initializer_list<std::reference_wrapper<...>>
,但它将阻止您将rvalue作为参数传递给构造函数,因为std::reference_wrapper
只能绑定到lvalue。换句话说,以下代码将无法编译:
YourContainerOfFunctions C{ [](){} };
在您的情况下,使用 std::initializer_list
既不高效也不方便。
我相信这就是您想要实现的:
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
};
}
每个参数最多需要一份副本,这是必要的,因为std::function
总是会复制从中构造的函数对象。一个例外是使用相同类型的std::function
构造std::function
。
std::initializer_list<int&> a = {...};
这样的吗? - R Sahu