MS Visual C++ 2012 バージョン 11.0.51106.01 Update 1 を使用する場合:
int x()
{
return 3;
}
template <typename Fun>
typename std::enable_if<std::is_same<Fun, int()>::value, int>::type
MySh(Fun& f)
{
return f();
}
template <typename Fun>
typename std::enable_if<std::is_same<Fun, int()>::value, int>::type
MySh1(Fun&& f)
{
return f();
}
template <typename Fun>
int MySh2(Fun&& f)
{
return f();
}
呼び出しコード:
int res = MySh(x); // compiles and returns 3
res = MySh1(x); // doesn't compile with error: error C2893: Failed to specialize function template 'std::enable_if<std::is_same<Fun,int(void)>::value,int>::type MySh1(Fun &&)
res = MySh2(x); // compiles and returns 3
他のコンパイラは (まだ) 試していませんが、Visual C++ 2012 で動作するようにするか、コンパイラのバグを Microsoft に報告することを目的としています。
些細なことを見落としてばかげた間違いを犯していないことを確認したい. もちろん、サンプルは単なる抜粋であり、実際の使用例はより複雑で、以下に関連しています 。
編集: 次のような他の考慮事項にも混乱しました:
std::is_same<decltype(x), int()>::value; // true
std::is_same<decltype(x), int(&)()>::value; //false
と:
template <typename Fun>
typename std::enable_if<std::is_same<Fun, int(&)()>::value, int>::type
MySh1(Fun&& f)
{
std::cout << typeid(f).name() << std::endl; // prints int __cdecl(void)
return f();
}
明らかに、パラメーターの型と引数の型の違いに注意を払っていませんでした (f や x とは対照的に楽しい)。