在C ++中的名称冲突 [英] name collision in C++

查看:198
本文介绍了在C ++中的名称冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写一些代码时,我遇到了这个问题:

  
#include > $ / b

类随机
{
public:
random(){std :: cout<< yay !!我叫\\\
;}
};

随机r1;

int main()
{
std :: cout<< entry !! \\\
;
static random r2;
std :: cout<< done !! \\\
;
返回0;



当我尝试编译这段代码时,
错误:“randomâ不命名一个类型。

当我为该类使用一些不同的名称时,代码工作正常。 b
看起来像 random 是在其他地方定义的(尽管编译器消息不是很有用)。



我的问题是,如何确保我使用的名称不会与包含文件中使用的名称相冲突。我尝试过使用命名空间,但是在通话时导致模糊。
任何见解?



我使用命名空间myNSpace作为命名空间

但是当我用它作为使用myNSpace :: random 时,它工作正常。

使用命名空间... 不起作用,而你的使用... c $ c>的作品?首先,我想向您展示另一种通过使用详细类型说明符来解决它的方法:

  int main(){
// ...
static class random r2; //在这里注意class
// ...
}

这是因为class some_class是一个详细的类型说明符,当查找指定的名称时,它将忽略任何非类型声明,因此具有相同名称的全局作用域中的POSIX函数不会隐藏类名称。您尝试了其他两种方法来解决这个问题:使用指令并使用声明:


  • 然后,您尝试将该类型粘贴到命名空间,并尝试 using namespace foo; in main - 为什么它不起作用?

      namespace foo {
    class random
    {
    public:
    random(){std :: cout<< yay !!我叫\\\
    ;}
    };
    }

    int main(){
    using namespace foo;
    static random r2; //含糊不清!
    返回0;

    $ / code>

    您可能想知道为什么会这样,因为您可能认为使用指令将 foo 的名称声明为main的本地范围 - 但事实并非如此。它没有声明任何名称,实际上它只是到另一个名称空间的链接。在这种情况下,它会在非限定名称查找过程中显示一个名称 - 但该名称作为包含using-directive和表示名称空间的名称空间的成员( foo )。封闭的命名空间是这里的全局命名空间。



    所以会发生什么是名称查找会找到该名称的两个声明 - 全局POSIX 随机声明,以及 foo 中的类声明。声明不是在同一个范围(声明区域)中进行的,所以函数名不会像平常一样隐藏类名(例如,参见 man stat )。确实),但结果是含糊不清。使用声明然而声明一个名字作为它出现的声明区域的一个成员。所以,当<$ c从 main 开始查找$ c> random ,它将首先找到一个名称,该名称引用 random在 foo ,这将有效地隐藏全局POSIX函数。所以下面的作品

      namespace foo {
    class random
    {
    public:
    random(){std :: cout<< yay !!我叫\\\
    ;}
    };
    }

    int main(){
    using foo :: random;
    static random r2; //起作用!
    返回0;
    }



While writing some code i came across this issue:


#include <iostream>

class random { public: random(){ std::cout << "yay!! i am called \n" ;} };

random r1 ;

int main() { std::cout << "entry!!\n" ; static random r2; std::cout << "done!!\n" ; return 0 ; }

When i try to compile this code i get the error
error: ârandomâ does not name a type.
When I use some different name for the class the code works fine.
Seems like random is defined somewhere else(although the compiler message is not very informative).

My question is how can i assure that a name i am using doesn't collides with a name used in included files. I have tried using namespaces but that leads to ambiguity at the time of call. Any insights?
[EDIT]
I used namespaces as using namespace myNSpace
But when i used it as use myNSpace::random it worked fine.

解决方案

Why does your using namespace... not work, while your using ... works? First i want to show you another way to solve it by use of an elaborated type specifier:

int main() {
  // ...
  static class random r2; // notice "class" here
  // ...
}

That works because "class some_class" is an elaborated type specifier, which will ignore any non-type declarations when looking up the name you specify, so the POSIX function at global scope, which has the same name, will not hide the class name. You tried two other ways to solve it: Using directives and using declarations:

  • Then, you tried to stick the type into a namespace, and tried using namespace foo; in main - why did it not work?

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    int main() {
     using namespace foo; 
     static random r2; // ambiguity!
     return 0 ;
    }
    

    You might wonder why that is so, because you might have thought that the using directive declares the names of foo into the local scope of main - but that's not the case. It's not declaring any name, actually it's just a link to another namespace. It's making a name visible during unqualified name lookup in that case - but the name is made visible as a member of the namespace enclosing both the using-directive and the denoted namespace (foo). That enclosing namespace is the global namespace here.

    So what happens is that name lookup will find two declarations of that name - the global POSIX random declaration, and the class declaration within foo. The declarations were not made in the same scope (declarative region), and so the function name doesn't hide the class name as usual (see man stat for an example where it does), but the result is an ambiguity.

  • A using declaration however declares one name as a member of the declarative region that it appears in. So, when random is looked up starting from main, it will first find a name that refers to the declaration of random in foo, and this will effectively hide the global POSIX function. So the following works

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    int main() {
     using foo::random; 
     static random r2; // works!
     return 0 ;
    }
    

这篇关于在C ++中的名称冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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