- C++相談室 part129 [無断転載禁止]©2ch.net
191 :デフォルトの名無しさん (ワッチョイ 6f56-3qL8)[sage]:2017/01/22(日) 02:40:24.62 ID:rrJzCAZR0 - 教えて下さい。
環境は VisualC++2015 x64 です。 与えられた文字列の引数について、1文字が1バイトなのか、2バイトなのかで呼び出す関数を切り分けたいと思い、SFINAE で以下のようなコードを書きました。 しかし、こののコードで「関数A」を呼んで欲しいのに、「関数B」が呼ばれてしまいます。 - なぜ関数Bが呼ばれるのか - 1文字のバイト数で切り替える手段 この2点について、教えて下さい。よろしくお願いします。 extern void* enabler; // 関数A (本当は1文字が1バイトの時用の関数) template <typename STR, std::enable_if_t<sizeof(decltype(std::remove_all_extents<STR>::type()[0])) == 1> *& = enabler> void hoge(const STR&) { } // 関数B (本当は1文字が2バイトの時用の関数) template <typename STR, std::enable_if_t<sizeof(decltype(std::remove_all_extents<STR>::type()[0])) != 1> *& = enabler> void hoge(const STR&) { int tmp; tmp = sizeof(decltype(std::remove_all_extents<STR>::type()[0])); // どういう訳か tmp == 1 となる } void main() { std::string s; hoge(s); // 1バイト版である、関数Aを呼んで欲しい }
| - C++相談室 part129 [無断転載禁止]©2ch.net
198 :191 (ワッチョイ 6f56-3qL8)[sage]:2017/01/22(日) 08:37:36.49 ID:rrJzCAZR0 - >192-196
ありがとうございます。 >193 確かに期待通りの動作をします。 ただ、この先 MFC の CStringA, CStringW, 生配列などを仮引数として与えたいため、operator[] の戻り値で判定出来ないか考えていました。 >196 なるほど。コンパイラの問題くさいので代替案を考えてみます。 ありがとうございました。
| - C++相談室 part129 [無断転載禁止]©2ch.net
199 :191 (ワッチョイ 6f56-3qL8)[sage]:2017/01/22(日) 08:50:18.71 ID:rrJzCAZR0 - >192-197
下の様に、sizeof, decltype を移動させたら、あっさり動きました。失礼しました。 template <typename STR> struct helper { enum { item_size = sizeof(decltype(STR()[0])), }; }; extern void* enabler; // 1バイト版 template <typename STR, typename std::enable_if<helper<STR>::item_size == 1>::type *& = enabler> void hoge(const STR&) { } // 2バイト版 template <typename STR, typename std::enable_if<helper<STR>::item_size == 2>::type *& = enabler> void hoge(const STR&) { } void main() { std::string a; hoge(a); // 1バイト版 std::wstring w; hoge(w); // 2バイト版 }
|
|