복사 생성자에서 C ++ 네임 스페이스 충돌


33

다음 코드가 있습니다.

namespace A {
    struct Foo {
        int a;
    };
}

struct Foo {
    int b;
};

struct Bar : public A::Foo {
    Bar(Foo foo) {
        c = foo.b;
    }
    int c;
};

A :: Foo에는 b라는 멤버가 없으므로 C ++ 컴파일러는 "c = foo.b"에서 불평합니다. :: Foo로 Bar 매개 변수의 유형을 변경하면 작동합니다.

내 질문은이 동작의 합리적인 이유입니다 (상속이 Bar가 A 네임 스페이스에 들어가게한다는 사실과 관련이 있다고 생각하지만이 이론을 뒷받침하는 문서를 찾을 수는 없습니다.


8
내가 생각하는 그것의 인수 종속 조회 관련. 언어 표준을 참조하는 답변을 찾은 후 "언어 변호사"라고 태그했습니다. 그리고 아주 좋은 첫 번째 질문입니다! 그것을 모두 가치있게 만듭니다.
Bathsheba

네임 스페이스를 입력하지 않습니다. 네임 스페이스를 입력하면 다른 구조체에서 상속 A했는지 확인할 수 있습니다 . 그런 다음 모호성이 없습니다. 그것은 상속이 모든 것을 추가 더 비슷 에 의 해상도를 포함 하는 방법에 대해 . 죄송하지만 더 정확하게 표현할 수는 없습니다. BarAA::FooBarFooA::Foo
n314159

@Bathsheba 템플릿에서 함수 이름 (또는 함수 템플릿 이름) 또는 종속 이름을 찾기위한 인수 유형 종속 이름 조회를 의미합니까?
curiousguy

답변:


22

모든 수업은 회원으로 이름이 주입되어 있습니다. 이름을 지정할 수 있습니다 A::Foo::Foo. 이것을 주입 된 클래스 이름이라고합니다.

[수업]

2 class-name은 class-name이 표시된 직후 선언되는 범위에 삽입됩니다. class-name은 클래스 자체의 범위에도 삽입됩니다. 이것을 injection-class-name이라고합니다. 액세스 확인을 위해 주입 된 클래스 이름은 마치 공용 멤버 이름 인 것처럼 처리됩니다.

[basic.lookup]

3 클래스의 삽입 클래스 이름은 이름 숨기기 및 조회를 위해 해당 클래스의 멤버로 간주됩니다.

인수 유형의 규정되지 않은 이름 검색은 클래스의 범위에서 시작 Bar하므로 해당 클래스의 멤버를 설명하기 위해 기본 클래스의 범위로 계속 진행됩니다. 그리고 A::Foo::Foo유형 이름으로 찾을 수 있습니다.

글로벌 유형 이름을 사용하려면 주변 (글로벌) 네임 스페이스로 이름을 규정하십시오.

Bar(::Foo foo) {
    c = foo.b;
}

주입 된 클래스 이름이 표시되지 않는 범위에서 정규화 된 조회를 수행하는 것입니다.

후속 "이유"질문에 대해서는


5
@TedLyngmo-ADL은 함수 호출에서 발생하며 특정 구절과 관련이 없습니다.
StoryTeller-언 랜더 모니카

오키, 나는 읽고 있었고 확실하지 않았다. 감사!
테드 Lyngmo

3
이것은 매우 재미 struct Bar:: A::Foo::Foo::Foo::Foo::Foo {}; 있지만 생성자를 지정하는 컨텍스트A::Foo::Foo있으므로 Foo원하는 만큼 계속 추가 할 수 없습니다 . 이것은 다음과 f같은 방법으로 함수를 호출 할 수 있다는 사실과 비슷하지만 (완전히 다른 메커니즘으로) 다음과 같습니다 (************f)().
AProgrammer

@AProgrammer-참으로. 그리고 더 재미있는 예제를 만들 수 있습니다 .
StoryTeller-언슬 랜더 모니카

이 답변은 확실히 "무엇"을 설명합니다. "이유"를 추가하여 개선 할 수 있습니까? 이 규칙의 목적은 무엇입니까? 어떤 유스 케이스가 개선되거나 가능합니까?
davidbak

2

완전한 답변 Bar은 아니며 ( 컴파일 이후)를 입력하지 않는 코드 만 표시 합니다 namespace A. 상속 할 때 A::Foo1모호함에 대한 문제는 없음을 알 수 있습니다.Foo 이 다른 수 Bar있습니다 A.

namespace A {
    struct Foo {
        int a;
    };

    struct Foo1 {
        int a;
    };
}

struct Foo {
    int b;
};

struct Bar : public A::Foo1 {
    Bar(Foo foo) {
        c = foo.b;
    }
    int c;
};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.