Visual C ++ 2010のバグですか、それとも正しい動作ですか?
template<class T>
T f(T const &r)
{
return r;
}
template<class T>
T f(T &&r)
{
static_assert(false, "no way"); //< line # 10
return r;
}
int main()
{
int y = 4;
f(y); //< line # 17
}
関数f(T &&)は決して呼び出されるべきではないと思いましたが、T = int&で呼び出されます。出力:
main.cpp(10):エラーC2338:まさか main.cpp(17):コンパイルされている関数テンプレートのインスタンス化'T f(T)'への参照を参照してください と [ T = int& ]
アップデート1リファレンスとしてC++x0コンパイラを知っていますか?comeauオンラインテストドライブを試しましたが、r値参照をコンパイルできませんでした。
アップデート2の回避策(SFINAEを使用):
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_reference.hpp>
template<class T>
T f(T &r)
{
return r;
}
template<class T>
typename ::boost::disable_if< ::boost::is_reference<T>, T>::type f(T &&r)
{
static_assert(false, "no way");
return r;
}
int main()
{
int y = 4;
f(y);
// f(5); // generates "no way" error, as expected.
}
アップデート3一部のコンパイラは、関数テンプレートのインスタンス化がない場合でも、static_assert(false、 "no way")でトリガーします。回避策(@Johannes Schaubに感謝-litb)
template<class T> struct false_ { static bool const value = false; };
...
static_assert(false_<T>::value, "no way");
また
static_assert(sizeof(T) == sizeof(T), "no way");