c++ - 为什么不能在 C++ 类中重新定义类型名称?

标签 c++ class scope typename

根据 C++ Primer 部分,7.4.1 Type Names Are Special:

Ordinarily, an inner scope can redefine a name from an outer scope even if that name has already been used in the inner scope. However, in a class, if a member uses a name from an outer scope and that name is a type, then the class may not subsequently redefine that name.

据此,例如:

typedef double Money;
class Account {
    public:
        Money balance() { return bal; }
    private:
        typedef double Money;
        Money bal;
};

int main() {
    typedef double Money;
    Money asset;
    typedef double Money;
    return 0;
}

当你编译上面的例子时,它会报错:

a.cc:6:24: error: declaration of ‘typedef double Account::Money’ [-fpermissive]
         typedef double Money;
                        ^
a.cc:1:16: error: changes meaning of ‘Money’ from ‘typedef double Money’ [-fpermissive]
 typedef double Money;

那么为什么我们不能在类中重新定义类型名称,但我们可以在内部范围内重新定义类型名称?


我的编译器版本是g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
该部分还有一条注释:

Although it is an error to redefine a type name, compilers are not required to diagnose this error. Some compilers will quietly accept such code, even though the program is in error.

最佳答案

这不是类型所独有的。 [basic.class.scope]/2:

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

原因是类范围内的名称查找有点特殊。考虑:

using Foo = int;

struct X {
    Foo a;    // ::Foo, i.e., int
    void meow() { 
        Foo b = a; // X::Foo; error: no conversion from int to char*
    }
    using Foo = char*;
};

成员函数体中的名称查找会考虑所有类成员,无论是在成员函数之前还是之后声明(否则,在类定义中定义的成员函数将无法使用类中稍后声明的数据成员)。结果是您得到两个具有不同含义的 Foo,即使它们在词法上都位于类成员 Foo 的声明之前。这很容易导致极其困惑和脆弱的代码,因此标准禁止它。

关于c++ - 为什么不能在 C++ 类中重新定义类型名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56178070/

相关文章:

c++ - 有没有办法通过函数指针调用运算符函数?

c++ - 方法名前的 const 是什么意思?

html - CSS - 无序列表 - 类,id 不工作

javascript - JSONP 回调和闭包/范围

angularjs - 如何使用循环遍历 Angular $scope 变量

c - 即使在下一次迭代之后,是否在循环中局部声明了一个变量,该循环创建了一个可以在被调用线程中安全使用的线程?

c++ - 指向函数参数与函数参数的指针?

c++ - 从 MS 访问调用 dll 函数

c++ - 使用 namespace 比使用类有优势吗?

java - 找不到类 JsonObject