2013-02-13 54 views
2

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

我有持久使用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 
    ); 
} 
+3

你看过程序集并检查副本是否实际上导致了任何额外的代码? – 2013-02-13 10:00:11

回答

4

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

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

+1非常棒!我将不得不评论代码来解释发生了什么 - thx。 – kfmfe04 2013-02-13 10:26:13

0

这应该是简单的:

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

而当你有它的std::string版本。也许您需要额外的重载,例如采取非常规参考。在C++ 11中,该函数应该在默认情况下模仿std::forward<T>

相关问题