编译器无法推断返回类型?

Compiler can't deduce the return type?

本文关键字:返回类型 编译器      更新时间:2023-10-16

我正在尝试在自动函数上使用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'

为什么编译器还没有推断出返回类型?

因为对于类定义,编译器将首先确定所有成员名称和类型。完成此操作,将分析函数体。

这就是为什么类成员函数可以调用在其自己的定义之后声明的另一个成员函数。

在编译确定时

using type_t = decltype(foo());

foo()身体的功能尚未得到分析。

作为补救措施,您可以使用

static auto foo() -> decltype(12) {
return 12;
}

注意:

这种现象只适用于阶级。将编译类外的以下代码:

auto bar() { return 12; }
using t = decltype(bar());

这是因为类或结构中的using看到的是声明,而不是成员的定义。所以看到auto但没有看到return 12;.

如果不同,将是危险的,因为成员的定义可以使用定义的(usingtypedef)类型。

想象一下如下

struct Thing {
static auto foo() {
return type_t{};
}
using type_t =
decltype(foo());
};

>@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(); }
};

这失败了,不是因为在foo的定义生效时bar未知,而是因为尚未推断出其返回类型。

现在,虽然你的例子在理论上是明确的,但可能需要付出很多努力才能提出标准语言,允许你的例子,同时又足够狭窄,禁止我的两个例子。话又说回来,好处似乎充其量是微不足道的。