【发布时间】:2011-02-18 06:27:08
【问题描述】:
这是 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=整数& ]更新 1 你知道任何 C++x0 编译器作为参考吗?我已经尝试过 comeau 在线试驾,但无法编译 r-value 参考。
更新 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");
【问题讨论】:
-
我想知道
static_assert(false, ...)并不总是被触发是不是 Visual C++ 的特殊性?对于 G++,断言必须依赖于模板参数才能触发,除非函数被实例化。 -
我认为这是 Visual C++ 的“功能”。对其他编译器使用 'static_assert(sizeof(T) == sizeof(F), "no way")'。
-
不合规当然不是特征。无论如何,
sizeof(T) == 0是使断言始终失败但要依赖的好方法。 (我有一个always_false<T>::value模板。) -
@GMan 同意。我在引号中写了“功能”。一种幽默。
-
我添加了一个答案来指出这一点。由于问题是为什么会触发 static_assert,我认为最好有一个静态的答案。
标签: c++ visual-c++ c++11 visual-c++-2010 rvalue-reference