2

これをやろうとしたとき、私はちょうどテンプレートをいじっていました:

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::stringasを渡すと、これは明らかに機能しませんT。文字列は にキャストできないためchar*、しかし、この関数は、C スタイルのchar*配列と C++の両方std::stringをパラメーターとして渡して、それらを に変換できるようにコーディングできLPCSTRますか?

4

5 に答える 5

5

関数のオーバーロードを使用できます。

void print_error(char const* msg);
void print_error(std::string const& msg);
...
于 2012-01-25T11:22:16.073 に答える
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 */
}
于 2012-01-25T11:23:45.383 に答える
2

これを実現するにはいくつかの方法があります。1 つは、テンプレート化された関数を関数のオーバーロードと組み合わせることです。

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;
}

もう 1 つの方法は、値が 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;
}
于 2012-01-25T13:35:17.927 に答える
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;
}
于 2012-01-26T09:31:27.023 に答える
1

hmjd が提供するソリューションを少し詳しく説明すると、このソリューションは任意の文字列入力や整数などで機能するはずです。また、Windows でアクティブ化されたユニコードでも動作するはずです。

#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 */
}
于 2012-01-25T13:51:31.893 に答える