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

标签 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 将内联版本突出显示为一个适当的函数,但似乎对第一个感到困惑(是的,我知道这是一个小问题,但仍然如此)。

性能、灵 active 等怎么样?

最佳答案

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

现在,还不清楚真正的问题是什么。对于初学者,我不会围绕标准库功能编写包装器,因为那只会让您的代码更加晦涩难懂。无论您是否喜欢 std::make_sharedMakeShared 好还是坏,前者对任何 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 &)

MakeShared 的实现中没有 std::forward,作为参数传递给函数的右值将作为左值转发,导致分配新的字符串,复制数据,最后在完整语句结束时释放旧字符串。使用 std::forward,新分配的 std::string移出参数字符串。

关于C++11 模板函数别名与包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19572512/

相关文章:

c++ - DrawText 和文本裁剪

c++ - 警告:将 NULL 传递给“std::thread::thread”的非指针参数

c++11 - 使用默认实例为 c++ 对象创建 c-wrappers 并推导原型(prototype)

c++11 - SIGINT 未在此范围内声明

windows - 在 stdin 在 Windows 上阻塞时退出应用程序

c++ - 构建选项已更改,正在重建所有退出状态 1 [Error] Exit with code=1 MXChip Azure IoT Dev Kit

c++ - 在 Windows 上用 C/C++ 反汇编内存函数

c++ - vector 循环未到达所有元素

c++ - C++中的模板类

c++ - 是否定义了 ofstream 实现的默认模式?