下面的小示例显示了我的问题:
template<class T> struct X
{
static void xxx(T& x) { }
static void xxx(T&& x) { }
};
int main(int argc, char** argv)
{
int x = 9;
X<int>::xxx(x); // OK.
X<int&>::xxx(x); // ERROR!
return 0;
}错误信息(GCC):
错误:“T=int&的静态void::xxx(T&&)”不能重载
错误:使用“静态空X::xxx(T&)和T=int&”
为什么?T = int& -> T&被static void xxx(T& x)中的int&&所取代?
如果问题的答案是肯定的,那么:
T&不是一个lvalue引用,它变成了一个rvalue-reference!但事实并非如此:
template<class T> struct X
{
static void xxx(T& x) { }
};
int main(int argc, char** argv)
{
X<int&>::xxx(2); // ERROR!
return 0;
}错误信息(GCC):
错误:对‘X::xxx(Int)’的调用没有匹配函数
注:候选人为:静态void::xxx(T&)与T= int&
则T&与T = int&不等于T&&,也不是rvalue引用。但如果不是,为什么第一个例子不起作用呢?(这是一个递归问题!)
但是,指针类型没有出现类似的问题:
#include <iostream>
template<class T> struct X
{
static void xxx(T* x) { std::cout << **x << std::endl; }
};
int main(int argc, char** argv)
{
int x = 10;
int* xx = &x;
X<int*>::xxx(&xx); // OK. call X<int*>::xxx(int**)
return 0;
}为什么引用在这种行为中是不同的?
发布于 2010-08-22 17:51:15
C++11语言标准在§8.3.2dcl.ref/6 (为可读性重新格式化)中解释了这一工作原理:
如果类型模板参数或解密类型-speci
er表示对类型
T的引用的类型TR,则为
创建类型“cv T"
T“
TR“创建类型TR.。
让我们考虑一下您的示例(我已将您的T重命名为TR,因此它与上面的语言相匹配):
template<class TR> struct X
{
static void xxx(TR& x) { }
static void xxx(TR&& x) { }
};如果我们尝试用X (so,T = int)实例化TR = int&,那么xxx的实例化如下:
static void xxx(TR& x) { } --> static void xxx(int& x) { }
static void xxx(TR&& x) { } --> static void xxx(int& x) { }在第一种情况下,我们尝试创建一个“TR的lvalue引用”,它变成了“T的lvalue引用”,T是int,所以参数类型变成了int&。
在第二个例子中,我们尝试创建一个“对TR的rvalue引用”,它变成了TR,也就是int&。
参数类型对于两个重载都是相同的,因此出现了错误。
https://stackoverflow.com/questions/3542497
复制相似问题