c++ - 将 c++11 之前的设置函数更改为带有转发功能的现代模板化函数是个好主意吗

标签 c++ c++11

在我的类(class)中,我有很多 setXXX 函数,如下所示:

void setName(const std::string& newName) {
   name = newName;
}

这是大多数程序员在 C++11 之前会做的事情。

我了解到(来自 Effective Moderm C++ 的第 25 项)使用转发可以使这些函数更有效率。所以它们看起来如下:

template<typename T>
void setName(T&& newName) {
   name = std::forward<T>(newName);
}

我的问题是将所有此类 C++11 之前的设置函数转换为具有转发引用参数的模板是否是个好主意?我目前的理解是它总是有益的,至少我没有看到缺点。

最佳答案

Perfect forwarding 听起来很有趣,但我还没有将它用于 setter。 (虽然,我确实从事性能关键型软件的工作)

根据我的经验,我认为这会使您的代码更难理解,但没有太大好处。让我解释一下:

复杂度

从现在开始,此设置方法的每个调用者都需要在知道传递什么之前检查成员的类型。让我们假设一个方法“setFile”:

template<typename T>
void setFile(T &&file) { m_file = std::forward<T>(file); }

我们应该用字符串(文件名)、c 风格的文件句柄、文件流、你的库特定的文件包装器来调用这个方法吗?看到这个方法,不清楚用哪个。如果您是代码库的新手,尤其如此。

即使您的类可以很小,可以放在一个终端屏幕上,代码完成也无法为您提供所需的信息。

请注意,如果您使用了错误的类型,编译错误也会变得更加复杂。

收获

这让我们想到了一个问题:您获得了什么?从现在开始,您使用完美转发。换句话说,您可以将 const char * 分配给 std::string 而不会产生性能开销。然而,这样的收获有多大?如果您有性能关键代码,则此重载已经存在。但是,如果代码对性能的要求不高,那么损失几个 CPU 周期也没有关系。

最重要的是,您的编译器(Clang、GCC、MSVC ...)是一个优化编译器。换句话说,它允许你编写你想要的代码而不必担心性能。 (不要误会我的意思,如果代码很关键,请担心,尽管相信许多编译器作者和研究人员会处理显而易见的问题)

因此,如果您有此 setName(const std::string &),请确保它已在 header 中实现,以便编译器可以对其进行推理并尝试将其优化为尽可能多。 (对于您自己的类,请确保所有构造函数、析构函数和赋值/强制转换函数对编译器可见)

结论

我怀疑花时间“升级”您的代码是否有用。如果它能带来那么多 yield ,那么基于 clang 的实用程序早就存在了。我什至敢打赌,通过花相同的时间分析您的应用程序和修复容易实现的成果,您会获得更高的性能。

关于c++ - 将 c++11 之前的设置函数更改为带有转发功能的现代模板化函数是个好主意吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42454853/

相关文章:

c++ - 为什么 Visual Studio 2013 对此类成员 decltype 有问题?

c++ - #define NULL nullptr 是否安全?

c++ - 模板化结构的括号括起来的初始值设定项列表

c++ - 将 URL 编码转换为可打印字符

c++ - 什么会导致 vkCreateDevice() 在没有给出失败原因的情况下失败?

c++ - 我可以仅针对 boost 单元测试失败获得日志输出吗

C++ 找不到兼容的标准构造函数

c++ - 使用 Eigen 张量类的问题

c++ - 在 C++ Firemonkey 平台中克隆对象

c++ - 如何检测类型是否为 std::tuple?