当我尝试这样做时,我只是在摆弄模板:
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++std::string
作为参数,并将它们转换为LPCSTR
吗?
您可以使用函数重载:
void print_error(char const* msg);
void print_error(std::string const& msg);
...
这将起作用:
#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 */
}
有几种方法可以实现这一点。一种是将模板化函数与函数重载相结合:
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;
}
为了稍微详细说明hmjd提供的解决方案,该解决方案应该适用于任何字符串输入,以及整数等。它还应该与在窗口上激活的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 */
}
如果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;
}