模板函数中的默认参数值,具体取决于类型

时间:2014-07-11 15:59:35

标签: c++ templates

假设我有这个函数来修剪std :: string并决定扩展它,这样它不仅会删除开头和结尾的空格,还会删除我在另一个字符串中传递的任何字符,如空格,换行符和运输回报。

std::string Trim ( const std::string &In_Original,
  const std::string &In_CharsToTrim = " \n\r" );

基本上,它会从In_Original的开头和结尾删除In_CharsToTrim中的所有字符。

现在,我必须为std :: string和std :: wstring写这个。由于我发现这很荒谬,我选择使用模板,并且它可以工作,但是我无法传递默认值,因为std :: wstring版本必须得到L" \n\r"作为默认值(请注意L,那里。

我试过了:

template <typename Type> Type Trim ( const Type &In_String,
  const Type &In_TrimCharacters );

以及:

template std::string Trim ( const  std::string &In_String,
  const  std::string &In_TrimCharacters = " \n\r" );
template std::wstring Trim ( const  std::wstring &In_String,
  const  std::wstring &In_TrimCharacters = L" \n\r" );

但它没有用。它甚至没有编译。

目前,我所拥有的是一个单独的函数,当你在没有第二个参数的情况下调用时,这是完全错误的方法:

template <typename Type> Type Trim ( const Type &In_String,
  const Type &In_TrimCharacters );
std::string Trim ( const std::string &In_String );
std::wstring Trim ( const std::wstring &In_String );

然后,在这个简单的Trim函数中,我只是调用完整版本。

所以,基本上,我要问的是......:

如何根据模板类型传递不同的默认值?基本上是一种特殊化,其中唯一的变化是默认参数......

在这种情况下,要在一个案例中传递std::string ( " \n\r" ),在另一个案例中传递std::wstring ( L" \n\r" ) ......

或者......还有另一种方法可以做我想做的事吗,在这里?

3 个答案:

答案 0 :(得分:3)

您可以使用简单的特征类并使用其::value作为默认参数。

template<typename T>
struct type_sensitive_default_argument;

template<>
struct type_sensitive_default_argument<std::string>
{
     static constexpr char value[] = "\n\r";
};

template<>
struct type_sensitive_default_argument<std::wstring>
{
    static constexpr wchar_t value[] = L"\n\r";
};

然后你可以这样做:

template<class Type,
         class Default = type_sensitive_default_argument<Type>>
Type Trim(const Type& In_String,
          const Type& In_TrimCharacters = Default::value);

答案 1 :(得分:2)

这就是我想出的:

template <typename T> struct default_trim_chars;

template<> struct default_trim_chars<std::string> { 
    static const char* value() { return " \n\r"; }
};

template<> struct default_trim_chars<std::wstring> { 
    static const wchar_t* value() { return L" \n\r"; }
};

template <typename Type> Type Trim ( const Type &In_String,
const Type &In_TrimCharacters = default_trim_chars<Type>::value()){
    /* ... */
}

您也可以将value声明为数据成员而不是函数,但这需要constexpr和C ++ 11。

答案 2 :(得分:1)

在您的情况下,您可能依赖于指定初始化字符列表来为您进行转换:

template <typename Type> Type Trim ( const Type &In_String,
  const Type &In_TrimCharacters = { ' ', '\r', '\n' } )
{
    // ...
}