2

背景

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

在模板参数是 a 的特殊情况下,std::string我使用它boost::regex_replace()来搜索\n和替换它\\n

问题

代码工作正常,但如果我可以在通用情况下摆脱额外的副本,那就太好了,因为 return-by-value

有没有办法在允许专用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
    );
}
4

2 回答 2

4

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

std::string protect_backslash_n( std::string const& orig);
于 2013-02-13T10:01:19.900 回答
0

这应该很简单:

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

std::string你拥有的版本。也许您将需要额外的重载,例如采用非常量引用。在 C++11 中,该函数应该std::forward<T>在默认情况下模仿。

于 2013-02-13T09:59:36.933 回答