There are several ways to achieve this. One is to combine templated functions with function overloading:
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;
}
Another way is to partially specialize a class template (function templates cannot be partially specialized) to handle a tagged template argument which tells it that the value is an 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;
}