首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器不能推断返回类型吗?

编译器不能推断返回类型吗?
EN

Stack Overflow用户
提问于 2018-03-13 22:59:08
回答 3查看 2.1K关注 0票数 12

我试图在一个自动函数上使用decltype关键字:

代码语言:javascript
复制
struct Thing {
   static auto foo() {
     return 12;
   }
   using type_t =
       decltype(foo());
};

我得到了以下错误(gcc 7.4):

代码语言:javascript
复制
<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'

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-13 23:10:34

因为对于类定义,编译器将首先确定所有成员的名称和类型。在此基础上对功能体进行了分析。

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

在这一点上编译是确定

代码语言:javascript
复制
using type_t = decltype(foo());

功能foo()的身体还没有被分析。

作为一种补救办法,你可以用

代码语言:javascript
复制
static auto foo() -> decltype(12) {
  return 12;
}

注:

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

代码语言:javascript
复制
auto bar() { return 12; }

using t = decltype(bar());
票数 14
EN

Stack Overflow用户

发布于 2018-03-13 23:10:22

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

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

想象一下如下所示

代码语言:javascript
复制
struct Thing {
   static auto foo() {
     return type_t{};
   }
   using type_t =
       decltype(foo());
};
票数 4
EN

Stack Overflow用户

发布于 2018-03-14 13:17:52

@liliscent已经解释了编译示例的各个阶段,但是这里还有一个额外的还原论和荒谬:在方法主体中,您可以使用方法之后声明的同一个类的标识符,因为主体只有在解析完完整的类定义后才会被翻译。现在假设foo的推断类型在Thing的定义中是可用的。那么,我们应该能够合法地写出以下内容:

代码语言:javascript
复制
struct Thing {
    static auto foo() {
      return type_t{};
    }
    using type_t =
        decltype(foo());
};

那么type_t现在应该是什么呢?同样,不允许采取以下措施:

代码语言:javascript
复制
struct Thing {
    static auto foo() { return bar(); }
    static auto bar() { return foo(); }
};

这是失败的,不是因为barfoo定义生效时未知,而是因为它的返回类型还没有推导出来。

现在,虽然您的示例在理论上是明确的,但可能需要付出很大的努力才能提出允许您的示例的标准语言,同时又足够窄到可以禁止我的两个示例。再说一次,好处充其量似乎是微不足道的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49267213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档