我试图在一个自动函数上使用decltype关键字:
struct Thing {
static auto foo() {
return 12;
}
using type_t =
decltype(foo());
};我得到了以下错误(gcc 7.4):
<source>:6:25: error: use of 'static auto Thing::foo()' before deduction of 'auto'
decltype(foo());
^
<source>:6:25: error: use of 'static auto Thing::foo()' before deduction of 'auto'为什么编译器还没有推导出返回类型?
发布于 2018-03-13 23:10:34
因为对于类定义,编译器将首先确定所有成员的名称和类型。在此基础上对功能体进行了分析。
这就是为什么类成员函数可以调用在其定义之后声明的另一个成员函数的原因。
在这一点上编译是确定
using type_t = decltype(foo());功能foo()的身体还没有被分析。
作为一种补救办法,你可以用
static auto foo() -> decltype(12) {
return 12;
}注:
这种现象只适用于课堂。类之外的以下代码将编译:
auto bar() { return 12; }
using t = decltype(bar());发布于 2018-03-13 23:10:22
这是因为类或结构中的using看到的是声明,而不是成员的定义。所以请看auto,但没有看到return 12;。
如果不同,将是危险的,因为成员的定义可以使用定义的(using或typedef)类型。
想象一下如下所示
struct Thing {
static auto foo() {
return type_t{};
}
using type_t =
decltype(foo());
};发布于 2018-03-14 13:17:52
@liliscent已经解释了编译示例的各个阶段,但是这里还有一个额外的还原论和荒谬:在方法主体中,您可以使用方法之后声明的同一个类的标识符,因为主体只有在解析完完整的类定义后才会被翻译。现在假设foo的推断类型在Thing的定义中是可用的。那么,我们应该能够合法地写出以下内容:
struct Thing {
static auto foo() {
return type_t{};
}
using type_t =
decltype(foo());
};那么type_t现在应该是什么呢?同样,不允许采取以下措施:
struct Thing {
static auto foo() { return bar(); }
static auto bar() { return foo(); }
};这是失败的,不是因为bar在foo定义生效时未知,而是因为它的返回类型还没有推导出来。
现在,虽然您的示例在理论上是明确的,但可能需要付出很大的努力才能提出允许您的示例的标准语言,同时又足够窄到可以禁止我的两个示例。再说一次,好处充其量似乎是微不足道的。
https://stackoverflow.com/questions/49267213
复制相似问题