基本上,我想知道为什么编译器拒绝ptr2声明:
int main() {
// this one works
decltype(void())* ptr1;
// this one does not
decltype(void{})* ptr2;
}
Run Code Online (Sandbox Code Playgroud)
如果您认为这是一个函数指针,请查看此代码ptr1:
#include <iostream>
using namespace std;
template <class T>
void f(T t) {
cout << __PRETTY_FUNCTION__ << endl;
}
int main() {
decltype(void())* ptr;
f(ptr);
}
Run Code Online (Sandbox Code Playgroud)
输出是void f(T) [with T = void*].
dyp*_*dyp 11
[expr.type.conv]
2表达式
T(),其中是非数组完整对象类型或(可能是cv -qualified)类型T的simple-type-specifier或typename-specifier,它创建一个指定类型的prvalue,其值是由value产生的值 -初始化(8.5)类型的对象; 没有为该情况进行初始化.[...]voidTvoid()
NB void 是一个简单类型说明符.
3同样地,一个简单型说明符或类型名称说明符后跟一个支撑-INIT列表创建具有指定的指定类型的直接清单初始化(8.5.4)的一个临时对象支撑-INIT列表,并且其value是临时对象作为prvalue.
感谢Keith Thompson指出在/ 3中创建了一个临时对象,而在/ 2中创建了一个值.
当我们看一下[basic.types]/5
未完全定义的对象类型和
void类型是不完整类型(3.9.1).不应将对象定义为具有不完整类型.
现在很明显void{}不允许这样做,因为它会创建一个(临时)对象.void()但是"仅"会创建(pr)值.我不认为这两种情况的实现(行为)存在差异,但不同的语言规则适用于它们.其中一条规则禁止创建类型的对象void,因此错误.
广告decltype(void()):decltype(e)表达e.在[dcl.type.simple]/4中,适用的定义decltype(e)是:
否则,
decltype(e)是的类型e
(因为void()产生一个prvalue而不是id-expression).
因此,decltype(void())收益率void.
| 归档时间: |
|
| 查看次数: |
427 次 |
| 最近记录: |