![](/img/trans.png)
[英]Can I initialize an array using the std::initializer_list instead of brace-enclosed initializer?
[英]std::initializer_list not able to be deduced from <brace-enclosed initializer list>
我有一个类,其构造函数采用initializer_list
:
Foo::Foo(std::initializer_list<Bar*> bars)
如果我尝试直接使用大括号括起初始化列表创建对象,则会正确推导出initializer_list
:
Foo f ({ &b }); // std::initializer_list<Bar*> correctly deduced
但是,当尝试间接执行相同操作(使用可变参数函数模板 - 在本例中为make_unique
)时,编译器无法推导出initializer_list
:
std::make_unique<Foo>({ &b }); // std::initializer_list<Bar*> not deduced
错误输出:
错误:没有用于调用
'make_unique(<brace-enclosed initializer list>)'
匹配函数
问题:
{ &b }
作为initializer_list<Boo*>
? std::make_unique<Foo>({ &b })
? 完整示例如下:
#include <initializer_list>
#include <memory>
struct Bar
{};
struct Foo
{
Foo(std::initializer_list<Bar*> bars)
{ }
};
int main()
{
Bar b;
// initializer_list able to be deduced from { &b }
Foo f ({ &b });
// initializer_list not able to be deduced from { &b }
std::unique_ptr<Foo> p = std::make_unique<Foo>({ &b });
(void)f;
return 0;
}
支撑的初始化程序没有类型。 当你调用make_unique
它会尝试推断出类型并失败。 在这种情况下,您必须在调用时指定类型
std::make_unique<Foo>(std::initializer_list<Bar*>{ &b });
这将创建一个std::initializer_list<Bar*>
,编译器可以推导出它,并将它转发给Foo::Foo(std::initializer_list<Bar*> bars)
原因Foo f ({ &b });
工程是编译器知道构造函数Foo(std::initializer_list<Bar*> bars)
,并且B*
s的支撑初始化列表可以隐式转换为std::initializer_list<Bar*>
。 没有类型扣除。
make_unique
使用完美转发。
完美转发在以下方面是不完美的:
它无法转发初始化列表
它将NULL
或0
转换为整数,然后不能将其传递给指针类型的值。
它不知道它的参数是什么类型,所以你不能做需要知道它们类型的操作。 举个例子:
struct Foo { int x; }; void some_funcion( Foo, Foo ) {}; template<class...Args> decltype(auto) forwarding( Args&& ... args ) { return some_function(std::forward<Args>(args)...); }
调用some_function( {1}, {2} )
是合法的。 它使用{1}
和{2}
构造Foo
。
呼叫forwarding( {1}, {2} )
不是。 它在您调用forwarding
时不知道参数将是Foo
,因此它无法构造它,并且它无法通过代码传递构造初始化列表(因为构造列表不是变量或表达式)。
如果传递重载的函数名称,则无法在调用点处计算出哪个重载。 并且一组重载不是一个值,所以你不能完美地转发它。
你无法通过位域传递。
它强制引用其参数,即使转发的目标没有。 这“使用”某些静态const数据的方式会导致程序在技术上形成错误。
无法转发对未知大小T(&)[]
的数组的引用。 但是,您可以使用T*
调用函数。
其中大约一半是从这个comp.std.c ++线程中获取的 ,我记得有一次,我记得有其他问题我无法回想起来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.