C ++ 11模板函数别名与包装器

时间:2013-10-24 17:22:59

标签: c++ templates c++11 alias

在底部使用以下内容有什么好处吗?还有其他方法可以创建模板函数别名吗?

template <typename T, typename... Args>
auto MakeShared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) 
{
    return std::make_shared<T>(std::forward<Args>(args)...);
}

template <typename T, typename... Args>
inline SharedPtr<T> MakeShared(Args&&... args)
{
    return std::make_shared<T>(args...);
}

最后一个看起来对我来说更具可读性了,而且,更多的是,Visual Assist强调内联版本就像一个正确的功能,但似乎对第一个感到困惑(是的,我知道这是一个小问题,但仍然)。

性能,灵活性等怎么样?

1 个答案:

答案 0 :(得分:2)

你不能别名功能,你可以编写新的功能,将实际的工作转发给现有的功能,但你不能只提供别名。

现在,尚不清楚真正的问题是什么。对于初学者,我不会围绕标准库功能编写包装器,因为这只会使您的代码更加模糊。你更喜欢std::make_shared更好或更差MakeShared,前者是任何C ++程序员都知道的,而前者是非显而易见的,需要查找。 (我个人不喜欢以大写字母开头的函数名称,但这是一个不同的问题。)

如果问题是关于实现的,考虑到你已经知道包装器的返回类型,我不会使用decltype,这实际上使代码更加模糊。但使用std::forward

仍然很重要
template <typename T, typename... Args>
std::shared_ptr<T> MakeShared(Args&&... args)
{
    return std::make_shared<T>(std::forward<Args>(args)...);
}

当类型更易于编写并且根本不依赖于参数时,添加尾随返回类型和decltype是荒谬的无意中键入。需要std::forward来提供模板参数的完美转发。否则,您最终可能会调用构造函数的错误版本:

std::string f();
auto p = std::make_shared<std::string>(f());
    // calls std::string(std::string &&)
auto q = MakeShared<std::string>(f());          // assume no std::forward was used
    // calls std::string(std::string const &)

std::forward的实现中没有MakeShared,作为参数传递给该函数的rvalue将作为左值转发,导致分配新字符串,复制数据并最终释放完整语句末尾的旧字符串。使用std::forward时,新分配的std::string移动从参数字符串中删除。

相关问题