使用std :: strings和c-style字符串时如何使用模板?

时间:2012-01-25 11:16:43

标签: c++ string templates cstring lpcstr

当我尝试这样做时,我只是搞乱了模板:

template<typename T> void print_error(T msg)
{
#ifdef PLATFORM_WIN32
    ::MessageBox(0, reinterpret_cast< LPCSTR >(msg), "Error", MB_ICONERROR|MB_OK);
#else
    cout << msg << endl;
#endif /* PLATFORM_WIN32 */
}

当然,如果您将std::string作为T传递,这显然不起作用。因为字符串不能转换为char*,但是这个函数的编码方式是允许我传递c风格的char*数组和c ++ {{1} }作为参数,并将它们转换为std::string

5 个答案:

答案 0 :(得分:5)

您可以使用函数重载:

void print_error(char const* msg);
void print_error(std::string const& msg);
...

答案 1 :(得分:3)

这样可行:

#include <sstream>

template<typename T> void print_error(T msg)
{
    std::ostringstream s;
    s << msg;

#ifdef PLATFORM_WIN32
    ::MessageBox(0, s.str().c_str(), "Error", MB_ICONERROR|MB_OK);
#else
    cout << s.str() << endl;
#endif /* PLATFORM_WIN32 */
}

答案 2 :(得分:2)

有几种方法可以实现这一目标。一种是将模板化函数与函数重载相结合:

template<typename T>
void print_error(T msg)
{
   ::MessageBox(0, reinterpret_cast< LPCSTR >(msg), "Error", MB_ICONERROR|MB_OK);
   cout << msg << endl;
}

void print_error(const std::string& msg)
{
   ::MessageBox(0, reinterpret_cast< LPCSTR >(msg.c_str()), "Error", MB_ICONERROR|MB_OK);
   cout << msg << endl;
}

int main()
{
string test = "test";
print_error(test);
print_error("test");
return 0;
}

另一种方法是部分地专门化一个类模板(函数模板不能部分专门化)来处理一个标记的模板参数,该参数告诉它该值是一个std :: string:

template <typename T>
class StringArgument{};

template <typename T>
struct ErrorPrinter
{
static void print_error(T msg)
{
   ::MessageBox(0, reinterpret_cast< LPCSTR >(msg), "Error", MB_ICONERROR|MB_OK);
}
};

template <typename T>
struct ErrorPrinter<StringArgument<T> >
{
static void print_error(T msg)
{
   ::MessageBox(0, reinterpret_cast< LPCSTR >(msg.c_str()), "Error", MB_ICONERROR|MB_OK);
}
};

int main()
{
string test = "test";   
ErrorPrinter<const char*>::print_error("sdfsdfsdf");
ErrorPrinter<StringArgument<string> >::print_error(test);

return 0;
}

答案 3 :(得分:1)

稍微详细说明hmjd提供的解决方案,此解决方案应该适用于任何字符串输入,以及整数等。它也适用于在Windows上激活的unicode。

#include <sstream>

template<typename T> void print_error(T msg)
{
#ifdef PLATFORM_WIN32
    std::basic_ostringstream< TCHAR > ss;
    ss << msg;
    ::MessageBox(0, ss.str().c_str(), "Error", MB_ICONERROR|MB_OK);
#else
    cout << msg << endl;
#endif /* PLATFORM_WIN32 */
}

答案 4 :(得分:1)

如果T是char,你可以启用print_error *否则它将是编译时错误,即(你需要包括type_traits和c ++ 11):

template<typename T> 
typename std::enable_if< std::is_same<T, char*>::value, void>::type print_error(T msg)
{
    ::MessageBox(0, reinterpret_cast< LPCSTR >(msg), "Error", MB_ICONERROR|MB_OK);
    cout << msg << endl;
}