模板推导和 decltype(T) 如何在引用上工作?
How does the template deduction and decltype(T) works on a refrence?
我正在学习C++模板。我不明白的是: 给定一个类型X
,并创建一个对象X a;
,如果我通过X& b = a;
定义对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
}
我的问题是为什么代码是这样工作的。
由于[expr.type]/1,b
作为表达式的类型X
:
如果表达式最初具有类型"引用 T"([dcl.ref], [dcl.init.ref](,则在进行任何进一步分析之前,该类型将调整为 T。
所以T
被推断为X
.然而,decltype(b)
不仅仅是作为表达式的b
类型。根据 [dcl.type.simple]/4(我不相关的部分被我省略了(:
对于表达式
e
,用decltype(e)
表示的类型定义如下:
。
否则,如果 e 是无括号的id 表达式或无括号的类成员访问,则
decltype(e)
是由e
命名的实体的类型。。
请注意,它是按b
命名的实体的类型(即X&
(,而不是表达式的类型b
。
试图回答问题的"为什么"部分:函数
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) { /* ... */ }
在调用时没有太多潜在的误解 - 参数是通过引用传递的。最后,这归结为整数是常规类型,而引用不是(请参阅这篇文章以获取最近的论文,也涵盖了指针(。
相关文章:
- C++编程:运算符重载中的引用如何工作?
- 推理类型如何工作"auto"和按引用调用?
- 继承引用无法正常工作
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- void*作为通用引用类型是如何工作的
- 模板推导和 decltype(T) 如何在引用上工作?
- 在 lambda 中通过引用捕获thread_local变量无法按预期工作
- 返回对局部变量的引用是否正常工作?
- 右值引用是否像右值引用一样工作
- 引用函数如何"int &foo();"工作?
- 我可以更改将引用参数传递到指针中并使其正常工作的函数的输入(C、C++)吗?
- r-工作程序中对自定义函数的未定义引用(C++和RcppParallel)
- 引用调用在 c++ 中如何工作?
- 如果不允许我分配 rvalues 来引用为什么以下代码片段有效,这在内部如何工作?
- STD ::配对的const引用如何工作
- 如何传入 std::shared_ptr 但"通过引用传递"工作?
- 代码块 C++ 停止工作可能是由于引用
- 与 C++ 相比,C# 中的按引用传递的工作方式是否正确?
- 返回const lvalue引用rvalue临时?为什么这项工作
- const和volatile的重载——为什么它可以通过引用工作