• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:テンプレート関数に関して質問です。)

テンプレート関数とwstring,stringの処理の違いについて

このQ&Aのポイント
  • テンプレート関数を使用して、wstringとstringに対して似たような処理を行いたい場合、Tによって値の変更が可能かどうかを調べたい。
  • また、似たような処理を行いたいが、変数の型を制限する方法はあるかを知りたい。
  • これらの質問についてご回答します。

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.7

マクロで書くなら、 #define make_func(T) \ void hoge(T &s)\ {\ s=TX("a");\ } #define TX(s) s make_func(std::string); #undef TX #define TX(s) L##s make_func(std::wstring); #undef TX これがせいぜいでしょうか。

glarelance
質問者

お礼

なるほど、これはいい感じですね。 #define make_func(T,TX) \ void hoge(T *s)\ {\ s[0]=TX##'a';\ } make_func(char,); make_func(wchar_t,L); という感じで利用してみることにします。 どうもありがとうございました。

その他の回答 (6)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.6

無名名前空間というのは、その名の通り「名前のないnamespace」です。 この空間内に記述されたものは外部ファイルから事実上アクセス不能になります。名前指定できないので。 マクロで作るというのは、テンプレートを使う代わりに全部マクロで書くということです。 #define make_func(T) \ void hoge(T &s) \ { \ s = "a" \ } make_func(wstring); make_func(string); こうすると、そもそもテンプレートでないため他の型は受け付けようがない、という訳です。 尤も、見ての通り特殊化は出来てませんが。

glarelance
質問者

お礼

色々テストしていて返信が遅れすみません。 これは、私のやりたいことにものすごく近いので、ものすごく惜しいですね・・・ #define make_func(T) \ #if T==char #define _TX_ #else #difine _TX_ L #endif void hoge(T &s) \ { \ s = _TX_"a" \ } みたいなこと出来ないかなーと試していたのですが、無理なようでした。 こんな感じのことは、マクロでは無理なんでしょうか?

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.5

こんな感じでできますが、これだとテンプレートにする意味がないですね。 template<class T> void hoge(T &s); template<> void hoge(std::string &s) { s="a"; } template<> void hoge(std::wstring &s) { s=L"a"; } たとえば、 void init(std::string &s) { s="a"; } void init(std::wstring &s) { s=L"a"; } template<class T> void hoge(T &s) { init(s); } こんなんでどうでしょう?

glarelance
質問者

お礼

うーん。それだと、関数の中で使われている全ての文字列に対して、関数を作らないといけなくなってしまいますね・・・

回答No.4

 こんばんは。  template<>については、テンプレートの特殊化というものです。  http://www.geocities.jp/ky_webid/cpp/language/037.html  Tにstd::stringが入れられた場合と、std::wstringが入れられた場合で、別の場所をコンパイルしているという事です。それ以外の方が入ればコンパイルエラーです。  ::については、::の前に何も書かれていなければ、そういう事になります。  http://www.geocities.jp/ky_webid/cpp/language/018.html  

glarelance
質問者

お礼

なるほど。よく分かりました。

  • colder
  • ベストアンサー率43% (30/69)
回答No.3

ここが参考になるかと http://ml.tietew.jp/cppll/cppll/article/13146

glarelance
質問者

お礼

解答ありがとうございます。 これは、なかなか良さそうなソースですね。 ただ、これだと、マルチバイト文字とワイド文字を両方保持することになるので、できれば、マクロのようにコンパイル時にwchar_t用の関数とchar用の関数を生成できるのが望ましいのですが・・・ void func(){   _T_CHAR *c=_TTX_"abc"; } のようなのを、コンパイル時に別のところへコピーして貼り付けて、 #define _T_CHAR char #define _TTX_ #define _T_CHAR wchar_t #define _TTX_ L というかんじで使い分けられたら一番良いのですが、この辺りがC++の限界ということでしょうか?

回答No.2

 こんばんは。  L"a"の代わりに以下のAPIで強引に変換してみては。  http://msdn.microsoft.com/ja-jp/library/cc448053.aspx  以下参考程度に。 #include<windows.h> #include<string> template<class T> struct Convert; template<> struct Convert<std::string> { //変換の必要がないのでそのまま通す static const std::string get(const std::string& mbcs) { return mbcs; } }; template<> struct Convert<std::wstring> { //LPSTRからLPWSTRへの変換 static const std::wstring get(const std::string& mbcs) { const int len = ::MultiByteToWideChar(CP_ACP, 0, mbcs.c_str(), -1, NULL, 0); LPWSTR p = (LPWSTR)::malloc(len * 2); ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mbcs.c_str(), -1, p, len); const std::wstring w(p); ::free(p); return w; } }; template<class T> void hoge(T &s) { s = Convert<T>::get("a"); } void foo(std::string &s) { ::hoge(s); } void foo(std::wstring &s) { ::hoge(s); } int main() { std::string str; ::foo(str); std::wstring wstr; ::foo(wstr); return 0; }

glarelance
質問者

お礼

解答ありがとうございます。 しょうもないことですみませんが、template<>のような無記名のtemplateは初めてみたのですが、どういう意味になるのでしょうか? また、::はどういう意味で使われているのでしょうか? グローバル空間に定義されてる関数を指しているという感じの意味ですか?

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

テンプレートでそれを実現するのは無理かと思います。 非共通部分は別々に実装し、共通部分のみテンプレートで合わせこむのがいいんじゃないでしょうか? 後者の方は、試した事はないですがテンプレートを無名名前空間内に放り込む事ができれば、外部からのアクセス遮断は行けるような気がします。 テンプレートではなくマクロで作ってしまえば固定的に展開できるので、想定外の型を入れることもできなくなりますが。

glarelance
質問者

お礼

解答ありがとうございます。 >テンプレートを無名名前空間内に放り込む事ができれば 馬鹿なことを聞いてるかもしれませんが、無名名前空間に放り込むとはどのようなことを仰っているのでしょうか? >マクロで作ってしまえば固定的に展開できるので、想定外の型を入れることもできなくなりますが。 マクロで作るというのは、どのようにすることを仰ってるのでしょうか?

関連するQ&A