Std::initializer_list和引用类型
std::initializer_list and reference types
std::initializer_list
可以包含引用类型(右值和左值)吗?还是必须使用指针或引用包装器(如std::ref
)?
可能需要更多的说明:
我有一个成员变量::std::vector<std::function<void()> >
,我想将一个lambda对象转发到其中。这通常是用emplace_back
完成的,但是我想在构造函数的初始化列表中完成。唉,当我阅读时,这将使转发不可能。
std::initializer_list
可以包含引用类型(右值和左值)吗?
std::initializer_list<T>
不包含对其元素的引用。它使用复制语义,将其值保存为const
对象:
18.9
初始化列表[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>
中是最可行的解决方案。
From http://www.cplusplus.com/reference/initializer_list/initializer_list/
initializer_list对象被自动构造为一个数组类型T的元素
因此它们不能与std::initializer_list<int&>
之类的东西一起使用。原因与下面给出编译错误的原因相同
int& arr[20];
错误:将' arr '声明为引用数组
,这是c++标准规定的:https://stackoverflow.com/a/1164306/1938163
这里不需要初始化列表
正如其他人提到的,您不能将std::initializer_list
用于引用。您可以使用std::initializer_list<std::reference_wrapper<...>>
,但它将阻止您将右值作为参数传递给构造函数,因为std::reference_wrapper
只能绑定左值。换句话说,以下代码将无法编译:
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
总是复制构造它的functor对象。一个例外是从相同类型的std::function
构造std::function
- 强制转换为引用类型
- 自定义引用类型
- Java 中是否有类似于 C++ 中引用类型"&"的内容?
- 为什么我不能在运算符=中使用引用类型?
- 可变参数模板函数参数和引用类型推导
- 隐式可转换参数,但属于引用类型
- 如何告诉自动推断向量<bool>元素的非引用类型
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- 引用类型的数据成员提供有关恒常正确性"loophole"
- 为什么引用类型在使用临时对象访问时是左值
- 什么是常量指针常量引用类型的参数?(const X* const & p)
- 在 lambda 中从引用类型捕获的值的类型,不使用通用捕获
- 如果类在 C++ 中具有常量或引用类型的非静态数据成员,为什么编译器不提供默认赋值运算符?
- void*作为通用引用类型是如何工作的
- 强制转换为不相关的引用类型是否违反严格的别名规则?
- C++ 引用类型作为递归函数参数
- EXPECT_CALL具有 unique_ptr 引用类型参数的模拟函数
- 如果使用返回引用的函数初始化"auto"var,为什么它不声明引用类型?
- 为什么模板引用类型不能用作模板类型别名参数?
- 模板默认参数将丢失其引用类型