1)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg arg)
{
return shared_ptr<T>(new T(arg));
}
2)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg& arg)
{
return shared_ptr<T>(new T(arg));
}
3)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg const & arg)
{
return shared_ptr<T>(new T(arg));
}
*)为什么数字3优先于数字1和数字2?
*)如果调用factory(41),为什么调用rvalue?
*)#define BOOST_ASIO_MOVE_ARG(type)type&amp;&amp ;.什么&amp;&amp;在这种情况下?
答案 0 :(得分:10)
实际上,方法#3 不优于1和2.这完全取决于T
的构造函数。
执行此操作的一种有些标准方法是使用 rvalue 引用,这是您提到的&&
。
所以,一个更好的工厂将是这样的:(这是完美转发实际上是什么)
template<typename T, typename Arg>
std::shared_ptr<T> factory(Arg && arg)
{
return std::shared_ptr<T>(new T (std::forward<Arg>(arg)));
}
由于引用折叠 C ++规则,此函数可以(并转发)rvalue refences和lvalue引用,即,如果你传递rvalue,它会忠实地将该rvalue转发给{ {1}}的构造函数,如果给它一个左值,那么两种引用(T
)将会崩溃,并且左值引用将被转发到底层构造函数。
我想我在这里覆盖了你的问题,但要明确回答,
Something & && arg
函数的const&
和&
重载。 factory
版本更好,它实际上会接受临时值,但如果你的基础const&
类型有一个接受非const ref的构造函数,那么你会得到一个编译错误,因为{{1不会隐式转换为T
。const&
的地址(这在技术上并非100%正确,但我认为以这种方式考虑左值和右值是可以的。)&
。你需要阅读这个;一个解释不适合这里,并且已经有几个伟大的只是谷歌搜索了! 更新:正如在评论中切向提到的那样,使用41
可能比使用只有rvalue reference
ed指针构建make_shared
更好。 shared_ptr
可以通过分配控制块(包括引用计数)以及对象本身来实现更高的效率,这将在访问引用计数器和对象时提供更好的缓存局部性,并且还可以节省一个内存分配。即使实现没有优化,也不会比上面的版本差。所以尽可能使用new
!这就是你在这里做的方式:
make_shared
答案 1 :(得分:1)
如果*)为什么数字3优先于数字1和数字2?
Arg
不可复制,则(1)将无效。
(2)不允许你传递右值,如factory<int>(42);
请注意,这三个示例都不涉及完美转发。我不确定你问题的主题是什么。
*)如果调用factory(41),为什么在rvalue上调用?
我不确定我理解这个问题。根据定义,41
是一个右值。
*)#define BOOST_ASIO_MOVE_ARG(type)type&amp;&amp ;.什么&amp;&amp;在这种情况下?
type&&
是rvalue reference到type
。