【问题标题】:Why does the compiler require the class qualifier on the return type of an already class-qualified member function definition?为什么编译器在已经类限定的成员函数定义的返回类型上需要类限定符?
【发布时间】:2016-05-27 19:56:27
【问题描述】:

我有点不确定描述这个问题的措辞,但举个例子:

Foo.h

namespace sample {

  class Foo {
    public:
      enum Bar {
        kValue1,
        kValue2,
      }

      Bar SomeMethod(Bar some_value);
  } 
}  // namespace sample

Foo.cc

namespace sample {

  Bar Foo::SomeMethod(Bar some_value) { // compiler complains here
    if (some_value == Bar::kValue1) {
      return Bar::kValue2; // but not here
    } else {
      return Bar::kValue1;
    }
  }
}  // namespace sample

编译器抱怨定义中的返回类型:

错误:未知类型名称“Bar”

为什么给SomeMethod 的定义提供限定条件Foo::SomeMethod 并没有将相同的限定条件扩展到Bar 的返回类型,而是将限定条件扩展到Bar 在此方法中的所有其他用途定义?

【问题讨论】:

  • 简答——因为这就是语言语法。
  • 这类为什么问题除了“这就是语言的设计方式”之外很难回答。
  • @CaptainGiraffe 不是“为什么这种语言是这样的”,我认为它的意思是“这两个位置有什么不同使得一种语法起作用而不是另一种”,但你有一个有效的观点。
  • 如果我没记错的话,在这种情况下Foo::SomeMethod(Foo::Bar some_value) 的参数需要 98 次作用域解析(根据 James 的回答),以后的版本不会。
  • 也许两者兼而有之。 :-) 我知道“为什么是语言”部门的问题有点沉重,但我在互联网上也找不到答案,所以我认为还是值得的。

标签: c++ function-declaration


【解决方案1】:
  Bar Foo::SomeMethod               (Bar some_value)
//^^^ Here is "outside" the class    ^^^ Here is "inside" the class

由于Bar 是在类中定义的,因此需要使用Foo:: 前缀来访问它,除非您在类本身中。

【讨论】:

    【解决方案2】:

    这是一个名称查找问题。通常,除非您在参数列表或函数体中,否则您不会自动看到 Foo 的内部:

    namespace sample {
    
      class Foo {
    
        public:
    
          enum Bar {
            kValue1,
            kValue2,
          };
    
          Bar SomeMethod(Bar some_value);
      }; 
    
      Foo::Bar Foo::SomeMethod(Bar some_value) {
        if (some_value == Bar::kValue1) {
          return Bar::kValue2;
        } else {
          return Bar::kValue1;
        }
      }
    } //namespace sample
    
    int main() {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 2021-08-15
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      相关资源
      最近更新 更多