2017-05-05 4 views
2
#include <iostream> 

using namespace std; 

class Test{ 
private: 
    Test(int a, int b=0) 
    { 
     cout << "private constructor\n"; 
    } 
public: 
    Test(int a) 
    { 
     cout << "public constructor\n"; 
    } 
}; 

int main() 
{ 
    Test t(1); 
} 

을에 후보로 개인 생성자를 제공 gcc 말한다 :컴파일러는 프로그램 코드

test.cpp: In function ‘int main()’: 
test.cpp:20:10: error: call of overloaded ‘Test(int)’ is ambiguous 
    Test t(1); 
     ^
test.cpp:12:2: note: candidate: Test::Test(int) 
    Test(int a) 
^
test.cpp:7:2: note: candidate: Test::Test(int, int) 
    Test(int a, int b=0) 
^
test.cpp:5:7: note: candidate: Test::Test(const Test&) 
class Test{ 
    ^

clang을 말한다 :

test.cpp:20:7: error: call to constructor of 'Test' is ambiguous 
     Test t(1); 
      ^~ 
test.cpp:7:2: note: candidate constructor 
     Test(int a, int b=0) 
     ^
test.cpp:12:2: note: candidate constructor 
     Test(int a) 
     ^
test.cpp:5:7: note: candidate is the implicit copy constructor 
class Test{ 
    ^
1 error generated. 

이의 이유는 무엇입니까 모호? Test(int,int)은 비공개이므로 Test t(1)으로 전화 할 수 없어야합니다. 가능한 대답은 (내가 처음 생각한 것), 생성자에 대한 두 개의 동일한 서명을 가능하게합니다. 즉, Test()은 개인 생성자에서 하나만 int과 함께 호출 할 수 있습니다. 그러나 프로그램 코드 Test t(1)은 공용 생성자에만 적합하므로 개인 생성자를 후보로 제공하면 안됩니다. 왜 그렇게 말하는거야?

+1

동일한 이유 : http://stackoverflow.com/questions/39042240/why-is-a-public-const-method-not- 예를 들면, 클래스 구현 파일에 상수를 도입하여 non-const-one-is-private/39042574 # 39042574 – NathanOliver

답변

4

그것은 표준에 따라 같은 명시적인 이유가 모호이다 : 가시성 회원들과 제어되는 기본 클래스에 대한 액세스 아니라는 것을 주목해야한다

[class.access/5]

. 구성원 이름은 여전히 ​​ 으로 표시되며 기본 클래스에 대한 암시 적 변환은 해당 멤버 및 기본 클래스에 액세스 할 수없는 경우에도 여전히 으로 간주됩니다. 주어진 구조의 해석은 액세스 제어에 관계없이 설정됩니다. 설정된 해석이 액세스 할 수없는 구성원 이름 또는 기본 클래스 인 을 사용하는 경우에는 구조가 이 아닙니다.

이 가시성이란 컴파일러가 구성에 과부하를 모두 고려해야한다는 것을 의미하며 전달 된 인수에 대해 똑같이 좋습니다.

생성자가 private이므로 클래스 및 멤버의 범위에서만 액세스 할 수 있으므로 기본 매개 변수 값을 제거하면됩니다. 다른 방법으로 클래스 정의에서이 기본값을 유지할 수 있습니다.

int const default_b = 0; 

// ... 

return Test{a, default_b}; 
이 같은
+0

대답에 대한 한 가지 정교함 : 액세스 권한이 확인되기 전에 이름 확인이 수행됩니다. +1. –