Ser*_*dar 4 c++ rvalue-reference visual-c++ visual-c++-2010 c++11
它是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
}
Run Code Online (Sandbox Code Playgroud)
我想,函数f(T &&)永远不应该被调用,但是用T = int&调用它.输出:
main.cpp(10): error C2338: no way
main.cpp(17) : see reference to function template instantiation 'T f(T)' being compiled
with
[
T=int &
]
更新1您是否知道任何C++ x0编译器作为参考?我已经尝试了在线测试驱动但无法编译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.
}
Run Code Online (Sandbox Code Playgroud)
更新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");
Run Code Online (Sandbox Code Playgroud)
要么
static_assert(sizeof(T) == sizeof(T), "no way");
Run Code Online (Sandbox Code Playgroud)
据我了解(我可能不完全正确;规范有点复杂),模板类型扣除规则对你不利.
编译器首先尝试替换所有模板(此时尚未选择 - 仅查找选项)并获取:
T const &r匹配int左值T = int,创造f(int const &)T &&r匹配int左值T = int&和int & &&减少到int&,创建f(int &)(规范中有规则说明).现在谈到选择正确的重载,后者是更好的匹配,因为第一个不同于cv资格而后者没有.这也是为什么当你删除它时const,你得到模糊的重载错误 - 重载最终完全相同.
Ad Update1:gcc支持许多C++ 0x功能.你可以从mingw获得本机windows 或使用cygwin.
广告UPDATE2:如果你真的需要为右值和左值分开过载,这似乎是唯一的选择.但是大多数模板只使用任何类型的引用做正确的事情,也许std::forward用于确保它们调用的函数的正确解析,这取决于它们是否具有rvalue或lvalue).
| 归档时间: |
|
| 查看次数: |
805 次 |
| 最近记录: |