具有相同名称的方法和内部类(错误:...与先前的声明冲突) [英] Method and inner class with the same name (error: ... conflicts with a previous declaration)

查看:169
本文介绍了具有相同名称的方法和内部类(错误:...与先前的声明冲突)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算有一个具有内部类的类和一个名称相似的方法。即使我有一个内部类和一个同名 B example1.cpp 的代码也可以毫无问题地编译。 c>。如果我将 Position 重命名为 position example2.cpp 不起作用c>小写字母。在这种情况下, position()方法和 position 类相互冲突,我收到:

I intend to have a class which has an inner class and a method with similar names. The code of example1.cpp compiles with no problem even though I have the an inner class and a method with the same name B. While example2.cpp will not work if I rename Position to position with small letters. In such a case, the position() method and the position class conflict with each other and I receive:

error: ‘ObjType::position<false> ObjType::position() const’ conflicts with a previous declaration
  inline auto position() const->class position<false>{return {*this};}
                                                                     ^
compilation terminated due to -Wfatal-errors.

这两个类之间有什么区别?为什么后一个给出错误而不是前一个错误?

What is the difference between these two classes? Why the latter one is giving error but not the former one?

g++ -std=c++11 exampleX.cpp -Wall -Wextra -Wfatal-errors && ./a.out

// example1.cpp

#include <iostream>

class A
{
public:
    friend class B;

    class B
    {
    public:
        int x;
        void show() {std::cout<<"x: "<<x<<std::endl;}
        B(): x(6) {}
    };

    B B()
    {
        class B b;
        return b;
    }
};

int main()
{
    A a;
    a.B().show();
    return 0;
}

// example2.cpp

#include <iostream>
#include <type_traits>

class Point
{
public:
    double x,y,z;
    void print() const
    {
        std::cout<<"x:"<<x<<", y:"<<y<<", z:"<<z<<std::endl;
    }
};

class ObjType
{
    template<bool> friend class Position;

    Point data;
public:
    template<bool ByRef>
    class Position
    {
        typename std::conditional<ByRef,ObjType&,ObjType const&>::type ref;
    public:
        inline Position(typename std::conditional<ByRef, ObjType&, ObjType const&>::type ref) : ref(ref) {}
        inline Position(const Point &ref): ref(ref){}
        inline auto operator =(Point const& a)->Position&{ref.data.subvec(0,2)=a; return *this;}
        inline auto operator =(Point&& a)->Position&{data=a; return *this;}
        inline void print() const{ref.data.print();}
    };

    inline ObjType(const Point &data): data(data){}
    inline void print() const{data.print();}
    /*error > */ inline auto position() const->class Position<false>{return {*this};}
    inline auto position()->class Position<true>{return {*this};}
};

int main()
{
    ObjType obj({1.1,1.2,1.3});
    std::cout<<"****************"<<std::endl;
    std::cout<<"obj.print() :"<<std::endl;
    obj.print();
    std::cout<<"obj.position.print() :"<<std::endl;
    obj.position().print();
    std::cout<<"****************"<<std::endl;
    return 0;
}


推荐答案


这两类之间有什么区别?为什么后一个给出错误而不是前一个出错?

What is the difference between these two classes? Why the latter one is giving error but not the former one?

我们可以进一步将您的示例简化为以下类:

We can further reduce your example to the following class:

struct S {
    struct C {};
    void C() {}
};

在这种情况下,标准不禁止引入已经使用其名称的类。确实确实对这种情况敞开了大门:

In this case, the standard doesn't forbid the introduction of a class the name of which is already in use. It's definitely opened to such a case indeed:


如果在范围内声明了类名,则该变量,函数或枚举数也要声明相同的名称,然后[...]

If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then [...]

它只是确定如何引用以及隐藏什么的规则。 br>
另一方面,请考虑以下类:

It just rules on how it can be referred and what hides what.
On the other side, consider the following class:

struct S {
    template<typename> struct C {};
    void C() {}
};

在这种情况下,标准严格禁止(有一些例外,此处均不适用):

In this case the standard strictly forbids it (with a few exceptions, none of which applies here):


类模板的名称不得与任何其他模板,类,函数,变量,枚举,枚举器,名称空间或同一范围内的类型

A class template shall not have the same name as any other template, class, function, variable, enumeration, enumerator, namespace, or type in the same scope

因此,您几乎不可能使用相同的标识符来命名类模板和其他函数。

您仍然可以将所有类型打包在一个封闭范围内无论如何,您都不会使用相同的名称定义函数。例如:

Therefore there is no chance you can name your class template and the other function around with the same identifier.
You can still pack all of your types within an enclosing scope where you don't define functions with the same name anyway. As an example:

struct S {
    struct T {
        template<typename>
        struct C {};
    };

    void C() {}
};

然后按以下方式访问它们:

Then access them as:

S::T::C<void> c;

这篇关于具有相同名称的方法和内部类(错误:...与先前的声明冲突)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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