Rom*_*n L 7 c++ templates pass-by-reference pass-by-value
我可以用这种方式编写模板化函数
template<class T> void f(T x) {...}
Run Code Online (Sandbox Code Playgroud)
或者这样
template<class T> void f(T const& x) {...}
Run Code Online (Sandbox Code Playgroud)
我猜第二个选项可以更加优化,因为它明确地避免了副本,但我怀疑它也可能因某些特定类型T(例如仿函数?)而失败.那么,什么时候应该使用第一个选项,何时使用第二个选项?还有这个boost::call_traits<T>::param_type和boost::reference_wrapper那个在我之前的问题的答案,但人们不到处使用它们,是吗?这有经验法则吗?谢谢.
Jam*_*lis 11
这有经验法则吗?
关于何时使用按引用传递与按值传递的相同的一般规则适用.
如果您希望T始终是一个数字类型或复制非常便宜的类型,那么您可以按值获取参数.如果你打算将参数的副本复制到函数中的局部变量中,那么你应该按值来获取它,以帮助编译器完全不需要创建副本.
否则,请参考参数.对于复制成本低廉的类型,它可能更昂贵,但对于其他类型,它会更快.如果您发现这是一个性能热点,您可以为不同类型的参数重载函数,并为每个参数执行正确的操作.
小智 5
你不会唤醒死者,但会遇到类似的问题,这里有一些示例代码,展示了如何使用 C++11 的类型特征来推断参数是应该通过值传递还是引用传递:
#include <iostream>
#include <type_traits>
template<typename key_type>
class example
{
    using parameter_type = typename std::conditional<std::is_fundamental<key_type>::value, key_type, key_type&>::type;
 public:
  void function(parameter_type param)
  {
      if (std::is_reference<parameter_type>::value)
      {
          std::cout << "passed by reference" << std::endl;
      } else {
          std::cout << "passed by value" << std::endl;
      }
  }
};
struct non_fundamental_type
{
    int one;
    char * two;
};
int main()
{
  int one = 1;
  non_fundamental_type nft;
  example<int>().function(one);
  example<non_fundamental_type>().function(nft);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)
希望它可以帮助其他有类似问题的人。