具体来说:直接列表初始化 (cppreference.com (3))。
在C++11中引入了
在我的经验中,声明临时结构以有效地向lambda提供一组参数等实际场景变得非常普遍:
所以我们只能使用
使用
这是另一个疏忽还是有一些理由来支持这个选择。具体来说,在列表初始化解决方案中可能会遇到哪些陷阱?
在C++11中引入了
std::make_shared
和统一初始化功能。因此,我们可以在堆上分配对象时使用聚合初始化:new Foo{1, "2", 3.0f}
。这是一种很好的直接初始化对象的方式,例如聚合体、pod等没有构造函数的对象。在我的经验中,声明临时结构以有效地向lambda提供一组参数等实际场景变得非常普遍:
void foo()
{
struct LambdaArgs
{
std::string arg1;
std::string arg2;
std::string arg3;
};
auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
auto lambda = [args] {
/// ...
};
/// Use lambda
/// ...
}
这里 auto args = std::make_shared<LambdaArgs>("1", "2", "3");
看起来很好,但是不会起作用,因为 std::make_shared
通常实现为:
template<typename T, typename... Args>
std::shared_ptr<T> make_shared(Args && ...args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
所以我们只能使用
auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
。使用
std::make_shared
解决的问题对于没有构造函数的对象仍然存在。而且这种解决方法不仅不美观,而且效率较低。这是另一个疏忽还是有一些理由来支持这个选择。具体来说,在列表初始化解决方案中可能会遇到哪些陷阱?
std::make_unique
后来在C++14中引入,为什么它也遵循同样的模式?
using LambdaArgs = std::tuple<std::string,std::string,std::string>
; - user4442671T{a,b}
和T(a,b)
可能会产生不同的效果。例如,对于T
=std::string
,它们具有不同的效果。理想情况下,除了旧的方法之外,应该有一种基于花括号的make_shared
,可以使用稍微不同的名称或带有一些消歧义的虚拟参数(标签)。 - Cheers and hth. - Alf