C++ 11の専門家にはいくつか質問があります。SFINAEとSFINAEでg ++とclang ++の動作が異なる
異なる動作を(3.5.0)++私はSFINAEと戦っていると私はグラムで奇妙なケースに出くわし++(4.9.2)、および打ち鳴らします。
私は、次のサンプルコードを用意しました。申し訳ありませんが、私はそれをもっと簡潔にすることができません。
#include <string>
#include <iostream>
#include <typeinfo>
#include <type_traits>
template <typename X>
class foo
{
private:
template <typename R>
using enableIfIsInt
= typename std::enable_if<std::is_same<X, int>::value, R>::type;
public:
foo()
{ }
template <typename R = void>
enableIfIsInt<R> bar()
{ std::cout << "bar: is int\n"; }
void bar()
{
std::cout << "bar: isn't int; is [" << typeid(X).name() << "]{"
<< typeid(enableIfIsInt<void>).name() << "}\n";
}
};
int main()
{
foo<long> fl;
foo<int> fi;
fl.bar();
fi.bar();
return 0;
}
私の考えでは(SFINAE経由)というテンプレートfoo<X>
クラスを作成することでしたX
テンプレート引数に応じて、1つまたは別の方法でメソッドを定義することができます。誰右:プログラムはG ++ 4.9.2が、打ち鳴らすとうまくコンパイル
++ 3.5.0は、次のエラー
test.cpp:13:36: error: no type named 'type' in
'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable
this declaration
= typename std::enable_if<std::is_same<X, int>::value, R>::type;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:26:23: note: in instantiation of template type
alias 'enableIfIsInt' requested here
<< typeid(enableIfIsInt<void>).name() << "}\n";
^
test.cpp:36:7: note: in instantiation of member function
'foo<long>::bar' requested here
fl.bar();
^
1 error generated.
を与える私は右打ち鳴らす++が、C++ 11人の専門家への私の最初の質問がされていると仮定しますか? g ++またはclang ++?
グラム++生成プログラムの出力について、それがfl.bar();
命令を無視しているようだ++以下
bar: isn't int; is [i]{v}
そうグラムです。
今はほとんど変化:私はこの方法で機能の醜態内std::enable_if
を削除
void bar()
{ std::cout << "bar: isn't int; is [" << typeid(X).name() << "]\n"; }
にfoo<X>::bar()
の第二のバージョンを変更します。今、両方のG ++と打ち鳴らす++問題なくコンパイルされ、出力は、プログラムの両方のコンパイルバージョンの、だから、
bar: isn't int; is [l]
bar: isn't int; is [i]
で、私の2番目の質問です:私が間違ってやっていますか?なぜ、int
の場合、の"is int"
バージョンが得られませんか?私はC++ 11を学ぶためにしようとしている:私はいくつかの愚かをやっている場合
は私と一緒に我慢して。
そして、私の悪い英語のため申し訳ありません。
は、あなたがより多くの最近の打ち鳴らすのバージョン(のような3.8)でこれを試してみましたし、より最近のgcc(5.3など)?教えてください... –
ほとんど最小化されたrepro:http://coliru.stacked-crooked.com/a/713fbbbca7e8b8c5。私はキャッシングを責める。 –
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70642 –