在编译时获取表达式的类型
Get type of expression at compile time
在使用auto
关键字进行编程时,有时知道编译器在编译时使用的类型是很方便的。如果编译在我需要知道类型的地方中止,这并不重要。简单的例子:
std::vector< int > s{1, 2, 3};
for (auto elem : s) {
elem = 5;
}
for (auto elem : s) {
std::cout << elem << std::endl;
}
将打印
1
2
3
是因为elem的类型是int
,而不是int&
。最好尝试编译代码并获得elem
的类型,以便尽早捕获此类错误。
经典的方法是声明模板结构而不定义:
template <typename> struct Debug;
,然后使用:
template struct Debug<std::string>;
或
for (auto elem : s) {
Debug<decltype(elem)>{};
elem = 5;
}
消息错误看起来像
error: explicit instantiation of 'struct Debug<std::__cxx11::basic_string<char> >' before definition of template
template struct Debug<std::string>;
^~~~~~~~~~~~~~~~~~
error: invalid use of incomplete type 'struct Debug<int>'
Debug<decltype(e)>{};
演示顺便说一句,现在一些ide显示类型时,鼠标在auto
或变量。
其实我刚刚找到了自己问题的答案:
template<typename T>
void show_type_abort_helper()
{
return __PRETTY_FUNCTION__;
}
#define show_type_abort(x) show_type_abort_helper< decltype(x) >()
用法:
std::vector< int > s{1, 2, 3};
for (auto elem : s) {
show_type_abort(elem);
elem = 5;
}
使用g++
(版本6.1.1)产生以下错误消息:
$ g++ test.cpp
test.cpp: In instantiation of ‘void show_type_abort_helper() [with T = int]’:
^^^
test.cpp:17:9: required from here
test.cpp:7:12: error: return-statement with a value, in function returning 'void' [-fpermissive]
return __PRETTY_FUNCTION__;
检查T = int
的输出,查看编译器使用int
作为类型。这似乎也适用于clang:
$ clang++-3.8 -std=c++11 test.cpp
test.cpp:7:5: error: void function 'show_type_abort_helper' should not return a value [-Wreturn-type]
return __PRETTY_FUNCTION__;
^ ~~~~~~~~~~~~~~~~~~~
test.cpp:17:9: note: in instantiation of function template specialization 'show_type_abort_helper<int>' requested here
^^^
show_type_abort(elem);
更改为for (const auto& elem : s)
给出
with T = const int&
^^^^^^^^^^
或
show_type_abort_helper<const int &>
^^^^^^^^^^^
所以看起来我可以在编译时找到类型并中止。对于由几个typedef和模板参数组成的非常复杂的类型,我无法看到发生了什么,这就派上了用场。
相关文章:
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 表观调用前面的表达式必须具有指向 func 类型的指针
- 数组类型 int[n][n] 不可赋值,因为表达式必须具有常量值
- 正则表达式以匹配数字的重复模式,后跟任何类型的分隔符?
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- 表达式必须具有类类型 vs.
- 错误:表达式必须具有算术、无作用域枚举或带有运算符重载的指针类型
- 非类类型表达式的静态类型与动态类型之间的差异
- 如何确定涉及 C++ 中除法的算术表达式的数据类型
- 结构化绑定初始值设定项表单 { 赋值表达式 } 对于 clang 上的数组类型失败
- 下标需要数组或指针类型表达式必须具有指针对象类型
- 带有数组类型表达式的错误分配
- 表示函数参数的元组的类型表达式
- 如何确定撤销类型表达式的更大类型
- c++ 11中有新的函数类型表达式格式吗?