为什么不能在C ++中的类中重新定义类型名称? [英] Why can't redefine type names in class in C++?

查看:309
本文介绍了为什么不能在C ++中的类中重新定义类型名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据《 C ++ Primer》一书,7.4.1类型名称是特殊的:

According to the book C++ Primer section, 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;
}

编译上面的示例时,它将抱怨:

When you compile the example above, it will complain:

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;

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

So why can not we redefine type names in class, but can we in the inner scope?

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

My compiler version is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609.
And there is also a note in that section:

尽管重新定义类型名称是错误的,但不需要编译器来诊断此错误.即使程序有错误,某些编译器也会悄悄接受此类代码.

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:

This is not unique to types. [basic.class.scope]/2:

在类S中使用的名称N应当在其类中引用相同的声明 上下文以及在S的完整范围中进行重新评估时.不 违反此规则需要进行诊断.

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.

原因是在类范围内的名称查找有些特殊.考虑:

The reason is that name lookup in class scope is a little special. Consider:

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.这很容易导致极其混乱和脆弱的代码,因此该标准禁止使用它.

Name lookup in member function bodies considers all class members, whether declared before or after the member function (otherwise, a member function defined in a class definition wouldn't be able to use a data member declared later in the class). The result is that you get two Foos with different meanings, even though they both lexically precede the class member Foo's declaration. This can easily lead to extremely confusing and brittle code, and so the standard bans it.

这篇关于为什么不能在C ++中的类中重新定义类型名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆