我想在我的课堂上拥有一个私有成员的spdlog记录器,甚至在文档中也建议这样做。首先令人失望:没有复制或移动spdlog :: logger的构造函数。因此,如果我想要一个更复杂的记录器,则必须跳过一些麻烦。让我们忽略它,只使用unique_ptr。
我无法使用make_unique从记录器构造唯一指针。不过,“手动”执行此操作效果很好。
std::unique_ptr<spdlog::logger> logger;
//works!
spdlog::logger* tmp = new spdlog::logger("logger", {console_sink, file_sink});
logger.reset(tmp);
//does NOT compile! "no matching function call to make_unique" - why?
logger = std::make_unique<spdlog::logger>("logger", {console_sink, file_sink});
为什么make_unique调用不起作用?
答案 0 :(得分:1)
函数模板不能推断初始化列表的参数类型( braced-init-list ),因此不能将{{{ 1}}得出了他们的(可变)自变量的 all 。编译器无法浏览该函数以查看make_unique
构造函数,但是直接使用spdlog::logger
,编译器就可以 try 解释初始化程序列表,其依据是( )在重载解析过程中的每个构造函数。
(可以通过传递明确的模板参数来避免推论,但这是麻烦的,至少(通常对于标准库来说)是禁止的。)
答案 1 :(得分:1)
make_unique
是一个函数模板,不能推断出您想将spdlog::sinks_init_list
作为第二个构造函数参数。
有效的方法如下:
std::make_unique<spdlog::logger>("logger", spdlog::sinks_init_list{console_sink, file_sink});
,因为您要指定第二个参数的类型。