【发布时间】:2016-05-15 19:55:00
【问题描述】:
我有一个类,其构造函数采用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;
}
【问题讨论】:
-
注意
Foo f ({ &b });中没有模板类型推导,而std::make_unique中有。 -
附注:使用
auto。make_unique的重点是能够使用类型推导。否则只写std::unique_ptr<Foo> p(new Foo{ &b });会更简单 -
@Starl1ght 更好的副本是Calling initializer_list constructor via make_unique/make_shared,但 Yakk 对这个问题的回答是所有 3 个问题中最好的回答