编译器无法推断返回类型?
Compiler can't deduce the return type?
我正在尝试在自动函数上使用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;
.
如果不同,将是危险的,因为成员的定义可以使用定义的(using
或typedef
)类型。
想象一下如下
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
未知,而是因为尚未推断出其返回类型。
现在,虽然你的例子在理论上是明确的,但可能需要付出很多努力才能提出标准语言,允许你的例子,同时又足够狭窄,禁止我的两个例子。话又说回来,好处似乎充其量是微不足道的。
相关文章:
- 在模板化成员函数的返回类型中使用 std::enable_if 时的编译器差异
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 为什么编译器不能从返回类型中推断出模板参数?
- 编译器无法推断返回类型?
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 为什么编译器无法推断返回类型?
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- typedef映射作为返回类型到函数会引发编译器错误
- 为什么编译器需要在已经类限定的成员函数定义的返回类型上使用类限定符
- 当我使用模板时,编译器无法将函数的返回类型从 double 转换为 int
- 函数声明和定义的返回类型不匹配,编译器可以吗?
- 编译器的函数返回类型验证
- C++ typedef 和返回类型:如何让编译器识别使用 typedef 创建的返回类型
- g++编译器忽略const返回类型
- 模板类中的尾随返回类型(GNU和Microsoft编译器之间的矛盾)
- 如何让编译器推断模板的返回类型
- 编译器警告:无法推导lambda返回类型
- 函数映射容器中C++函数返回类型重载:自动推导失败,并出现编译器错误
- 为什么编译器不显示这些返回类型的错误?
- 如何让编译器推断出c++ 11中模板化方法的返回类型