背景
我有一些使用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
);
}
答案 0 :(得分:4)
不要把它变成模板,而只是过载。如果参数匹配,编译器将在模板实例化上选择该函数。
std::string protect_backslash_n( std::string const& orig);
答案 1 :(得分:0)
这应该很简单:
template <typename T>
T const& protect_backslash_n(T const& orig)
{
return orig;
}
和std::string
版本一样。也许你需要额外的重载,例如采取一个非对象的参考。在C ++ 11中,该函数应该在默认情况下模仿std::forward<T>
。