c++ - C++ Primer 第 5 版第 16.5 章类模板专业化
问题描述
我认为这本书在第 711 页有一个错误:
在第 16.2.3 节(第 684 页)中,我们介绍了库
remove_reference
类型。该模板通过一系列专业化工作:// original, most general template template <class T> struct remove_reference { typedef T type; }; // partial specializations that will be used fore lvalue and rvalue references template <class T> struct remove_reference<T&> // lvalue references typedef T type; }; template <class T> struct remove_reference<T&&> // rvalue references typedef T type; };
...
int i; // declyptype(42) is int, used the original template remove_reference<decltype(42)>::type a; // decltype(i) is int&, uses first(T&) partial specialization remove_reference<decltype(i)>::type b; // delctype(std::move(i)) is int&&, uses second (i.e., T&&) partial specialization remove_reference<decltype(std::move(i))>::type c;
所有三个变量 ,
a
和b
,c
都具有类型int
。
我认为会decltype(i)
产生一个普通的int
,int&
因此在b
. 对于普通变量类型[1],decltype
类型说明符产生普通类型,而对于其他可以用作lvalue
的表达式,它将产生和lvalue reference
。
例子
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
template <typename T> struct blubb {
typedef T type;
void print() { cout << "plain argument type\n"; }
};
template <typename T> struct blubb<T&> {
typedef T type;
void print() { cout << "lvalue reference type\n"; }
};
template <typename T> struct blubb<T&&> {
typedef T type;
void print() { cout << "rvalue reference type\n"; }
};
int main() {
int i = 0;
blubb<decltype(42)> plain;
plain.print();
blubb<decltype(i)> lvalue_ref; // actually not!
lvalue_ref.print();
int* pi = &i;
blubb<decltype(*pi)> lvalue_ref2; // expression which can be on the left hand side
lvalue_ref2.print();
blubb<decltype(std::move(i))> rvalue_ref;
rvalue_ref.print();
return 0;
}
编译并运行
g++ -o types types.cpp -Wall -pedantic -g && ./types
plain argument type
plain argument type
lvalue reference type
rvalue reference type
请告诉我我是对还是错,并在适当的时候解释一下。
谢谢
[1]可能正确的术语是id-expression
?
解决方案
是的,对于未加括号的 id-expression,decltype
产生由 id-expression 命名的实体类型,然后decltype(i)
产生 type int
。
- 如果参数是未加括号的 id 表达式或未加括号的类成员访问表达式,则
decltype
产生由此表达式命名的实体的类型。
另一方面,decltype((i))
产生类型int&
; (i)
被视为左值表达式。
- 如果参数是任何其他类型的表达式
T
,并且
b) 如果表达式的值类别是左值,则 decltype 产生T&
;
请注意,如果对象的名称带有括号,则它被视为普通的左值表达式,因此
decltype(x)
通常decltype((x))
是不同的类型。
推荐阅读
- java - Java在同一个端口接收多个源的音频数据,如何分离播放
- c++ - 存储与任务关联的名称列表
- angular - Angular 6(和 7)中的 Mat-button-toggle 主题
- c# - .Net AsyncStateMachine 自定义实现行为
- workflow - 确定客户最后一次订购特定商品并让他们进入工作流程
- angular - PrimeNG:如何将页脚列组附加到冻结/固定视图
- youtube-api - 错误的 ResultsPerPage 输出项目数
- ios - 如何在浏览器和我的应用程序之间共享数据
- python - 以下哪一项是访问类中变量的最佳实践?
- python - 如何在 Python 2.7 中加速这个 Mersenne Prime py