如何避免通用函数模板中的额外副本

How do I avoid the extra copy in the generic function template?

本文关键字:副本 函数模板 何避免      更新时间:2023-10-16

背景

我有一些用于持久性的通用代码,它使用boost::variant来存储多种类型。在输出值时,我必须编写一个转换器函数protected_backslash_n,在默认情况下,它什么都不做,但返回相同的值。

在模板参数为std::string的特殊情况下,我使用boost::regex_replace()搜索n并将其替换为\n

问题

代码运行良好,但如果我能在通用情况下去掉额外的副本,那就太好了,因为值返回

有没有一种方法可以做到这一点,同时允许专业的std::string版本正常工作?

我尝试将返回值更改为T const&,但专用版本无法匹配。

错误

GetPipedValues.hpp:15:21: error: template-id ‘protect_backslash_n<std::string>’ for ‘std::string pitbull::protect_backslash_n(const string&)’ does not match any template declaration

代码

template<typename T>
inline T protect_backslash_n( T const& orig )
{
    return orig;  // BAD: extra copy - how do I get rid of this?
}
template<>
inline std::string protect_backslash_n<std::string>( std::string const& orig )
{
    boost::regex expr("(\n)");
    std::string  fmt("(\\n)");
    return boost::regex_replace(
        orig, expr, fmt, boost::match_default | boost::format_all
    );
}

不要让它成为一个模板,而只是一个重载。如果参数匹配,编译器将选择该函数而不是模板实例化。

std::string protect_backslash_n( std::string const& orig);

这应该很简单:

  template <typename T>
  T const& protect_backslash_n(T const& orig)
  { 
    return orig; 
  }

还有你拥有的std::string版本。也许你需要额外的重载,例如获取一个非标准引用。在C++11中,该函数在默认情况下应模仿std::forward<T>