我正在用C ++学习模板。我不明白的是:
给定类型X
并创建对象X a;
,如果我通过a
定义对X& b = a;
的引用,则std::is_reference<decltype(b)>::value
将返回true。但是,我将b作为模板函数的参数,扣除的类型不是引用。
#include <iostream>
class X {};
template<typename T>
void
F(T t)
{
if (std::is_reference<T>::value)
std::cout << "T is a reference" << std::endl;
}
int
main()
{
X a;
X &b = a;
std::cout << std::is_reference<decltype(b)>::value << std::endl; // return true
F(b); //return false
}
我的问题是为什么代码会像这样工作。
答案 0 :(得分:3)
由于[expr.type]/1,b
作为表达式的类型为X
:
如果表达式最初具有“对T的引用”类型([dcl.ref],[dcl.init.ref]),则在进行任何进一步分析之前将类型调整为T.
因此T
推断为X
。但是decltype(b)
不仅仅是b
作为表达式的类型。根据{{3}}(我无视相关部分):
对于表达式
e
,decltype(e)
表示的类型定义如下:
...
否则,如果e是未加密码的 id-expression 或未加密码的类成员访问,
decltype(e)
是由{{1}命名的实体的类型} 即可。 ......
请注意,它是由e
命名的实体的类型(即b
),而不是表达式X&
的类型。
答案 1 :(得分:1)
试着回答&#34;为什么&#34; -part of the question:The function
void someFunc(int arg) { /* ... */ }
明确地通过价值接受其论点。考虑到int
,你对这个函数有什么样的语义?
template<class T> void someFunc(T arg) { /* ... */ }
我希望参数也可以通过值传递。现在考虑调用片段,在第一种情况下
int i;
int& j = i;
someFunc(j); /* j passed by value. */
在第二种情况下
X a;
X& b = a;
someFunc(b); /* b passed by reference? Luckily not. */
使用功能模板签名而不是
template<class T> someFunc(T& arg) { /* ... */ }
在调用时没有太多潜在的误解 - 参数通过引用传递。最后,这归结为整数是常规类型,而引用不是(参见this post最近的论文,也包括指针)。