Compiler can't deduce the return type?

会有一股神秘感。 提交于 2020-01-11 00:57:50

问题


I am trying to use the decltype keyword on an auto function:

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

And I get the following error (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'

Why has the compiler not yet deduced the return type?


回答1:


Because for class definition, compiler will first determine all member names and types. Function body is analyzed after this is done.

That's why a class member function can call another member function declared after its own definition.

At the point compile is determining

using type_t = decltype(foo());

function foo()'s body has not yet been analyzed.

As a remedy, you can use

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

NOTE:

This phenomenon is only for class. The following code outside a class will compile:

auto bar() { return 12; }

using t = decltype(bar());



回答2:


It's because a using inside a class or struct see the declaration but not the definition of members. So see auto but doesn't see return 12;.

If different, would be dangerous because the definition of members can use the defined (using or typedef) types.

Imagine something as follows

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



回答3:


@liliscent has already explained the stages of compiling your example, but here is an additional reductio ad absurdum: In a method body, you can use identifiers from the same class that are declared after the method, because the body is only translated after parsing the full class definition. Imagine now that the deduced type of foo was available inside the definition of Thing. Then we should be able to legally write the following:

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

And what should type_t be now? Likewise, the following is not allowed:

struct Thing {
    static auto foo() { return bar(); }
    static auto bar() { return foo(); }
};

This fails, not because bar was unknown at the point where the definition of foo takes effect, but because its return type has not been deduced yet.

Now, while your example is unambiguous in theory, it would probably take a lot of effort to come up with standard language that allows your example while at the same time being narrow enough to forbid both of my examples. And then again, the benefit seems marginal at best.



来源:https://stackoverflow.com/questions/49267213/compiler-cant-deduce-the-return-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!