std :: initializer_list无法从<括号括起始化器列表>中推导出来。 [英] std::initializer_list not able to be deduced from <brace-enclosed initializer list>
问题描述
我有一个类的构造函数需要 initializer_list
:
I have a class whose constructor takes an initializer_list
:
Foo::Foo(std::initializer_list<Bar*> bars)
直接的对象, initializer_list
可以正确推导出来:
If I attempt to create an object with a brace-enclosed initializer list directly, the initializer_list
is correctly deduced:
Foo f ({ &b }); // std::initializer_list<Bar*> correctly deduced
但是,当试图做同样间接变量函数模板 - 在这种情况下 make_unique
),编译器无法推导出 initializer_list
:
However, when trying to do the same indirectly (with a variadic function template - in this case make_unique
), the compiler is unable to deduce the initializer_list
:
std::make_unique<Foo>({ &b }); // std::initializer_list<Bar*> not deduced
错误输出:
错误:没有匹配的函数调用
'make_unique(<括号括起始化列表>)'
问题:
- 为什么编译器无法将
{& b}
推导为initializer_list< Boo *>
li>
- 是否可以使用我想要的语法
std :: make_unique< Foo>({& b})
>
- Why is the compiler failing to deduce
{ &b }
as ainitializer_list<Boo*>
? - Is it possible to use the syntax
std::make_unique<Foo>({ &b })
which I desire?
完整示例如下:
#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;
}
推荐答案
完美转发在以下方面不完美:
Perfect forwarding is imperfect in the following ways:
-
它无法转发初始值列表
It fails to forward initializer lists
它转换 NULL
或 0
为一个整数,然后无法传递到指针类型的值。
It converts NULL
or 0
to an integer, which can then not be passed to a value of pointer type.
它不知道它的参数将是什么类型,所以你不能做需要知道他们的类型的操作。例如:
It does not know what type its arguments will be, so you cannot do operations that require knowing their type. As an example:
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} $ c $构造
Foo
c>。
Calling some_function( {1}, {2} )
is legal. It constructs the Foo
s with {1}
and {2}
.
调用转发({1},{2})
它不知道在你调用转发
的时候,参数将是 Foo
s,因此它不能构造它,并且它不能通过代码传递构造初始化列表(因为构造列表不是变量或表达式)。
Calling forwarding( {1}, {2} )
is not. It does not know at the time you call forwarding
that the arguments will be Foo
s, so it cannot construct it, and it cannot pass the construction-initializer-list through the code (as construction-lists are not variables or expressions).
如果传递一个重载的函数名,这种过载不能在呼叫点处计算出来。
If you pass an overloaded function name, which overload cannot be worked out at the point of call. And a set of overloads is not a value, so you cannot perfect forward it through.
不能通过位字段。
它强制引用它的参数,即使转发的目标没有。
It forces takes a reference to its arguments, even if the forwarded target does not. This "uses" some static const data in ways that can cause a program to be technically ill-formed.
引用未知大小的数组 T(&)[]
无法转发。
A reference to an array of unknown size T(&)[]
cannot be forwarded. You can call a function taking a T*
with it, however.
其中大约一半来自这个comp.std.c ++线程,我一次想起来,我记得还有其他问题,我不记得我的头顶。
About half of these were taken from this comp.std.c++ thread, which I looked for once I remembered there were other issues I couldn't recall off the top of my head.
这篇关于std :: initializer_list无法从<括号括起始化器列表>中推导出来。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!