1)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg arg)
{
return shared_ptr<T>(new T(arg));
}
Run Code Online (Sandbox Code Playgroud)
2)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg& arg)
{
return shared_ptr<T>(new T(arg));
}
Run Code Online (Sandbox Code Playgroud)
3)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg const & arg)
{
return shared_ptr<T>(new T(arg));
}
Run Code Online (Sandbox Code Playgroud)
*)为什么3号比1号和2号更受欢迎?
*)如果调用工厂(41),为什么要调用右值?
*)#define BOOST_ASIO_MOVE_ARG(type)type &&.在这种情况下什么是&&?
yzt*_*yzt 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)));
}
Run Code Online (Sandbox Code Playgroud)
由于参考 C++的折叠规则,这个函数可以接受(并转发)rvalue refences和lvalue引用,也就是说,如果你传递一个rvalue,它会忠实地将rvalue转发T给它的构造函数,如果给它一个左值,这两种reference(Something & && arg)将崩溃,并且左值引用将被转发到底层构造函数.
我想我在这里覆盖了你的问题,但要明确回答,
const&和&重载factory.该const&版本是更好的,它实际上会接受临时值,但如果你的基础T类型有接受非const ref上的构造函数,那么你会得到一个编译错误,因为const&没有隐含浇铸为&.41(这在技术上并非100%正确,但我认为以这种方式考虑左值和右值是可以的.)rvalue reference.你需要阅读这个; 一个解释不适合这里,并且已经有几个伟大的只是谷歌搜索!更新:正如在评论中切向提到的那样,使用make_shared可能比shared_ptr使用刚刚new指针构造一个更好.make_shared通过分配控制块(包括引用计数)以及对象本身可以实现更高的效率,这将在访问引用计数器和对象时提供更好的缓存局部性,并且还可以节省一个内存分配.即使实现没有优化,也不会比上面的版本差.所以std::make_shared尽可能使用!这就是你在这里做的方式:
template<typename T, typename Arg>
std::shared_ptr<T> factory (Arg && arg)
{
return std::make_shared<T>(std::forward<Arg>(arg));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2386 次 |
| 最近记录: |