2016-11-14 3 views
0

다음과 같이 내가 불변 String 클래스가 있다고 가정 :오버로드 해결 : 명시 적 및 초기화 구문의 역할은 무엇입니까?

#include <iostream> 
#include <string> 

class String 
{ 
public: 
    explicit String(const char *Value) : Size(std::strlen(Value)), Value(new char[Size + 1]) 
    { 
     std::memcpy(this->Value, Value, Size + 1); 
     std::cout << Value << ", novice." << Size << std::endl; 
    } 
    template <typename T, std::size_t N> String(const T (&Value)[N]) : Size(N - 1), Value(new char[N]) 
    { 
     std::memcpy(this->Value, Value, N); 
     std::cout << Value << ", expert." << Size << std::endl; 
    } 
    ~String() 
    { 
     delete[] Value; 
    } 
private: 
    const std::size_t Size; 
    char *Value; 
}; 

void main() 
{ 
    auto &s = "Welcome to C++"; 
    String string = s; 
    String str {s}; 
    String st(s); 
    return; 
} 

내가 역할 explicit 재생 방법 생성자 오버로드가 선택 될 때 초기화 구문은 차이가 알고 싶어요.


나는 strst, 나는 명시 적으로 const char에 대한 포인터를 취하는 생성자를 호출하고 있음을 이해하고, 그래서 그들은 인쇄 :

Welcome to C++, novice. 
Welcome to C++, novice. 

하지만 string

에 대한 이유를 이해하지 않습니다
Welcome to C++, expert. 

이 인쇄됩니다. 과부하가 선택되는 방법을 명확히하십시오. 이 템플릿되지 않으므로

String str {s}; 
String st(s); 

explicit String(const char *Value) 

포인터 과부하가 선택되는 이유

+0

문자열 클래스는 다른 불변 C 스타일 문자열로 초기화하는 경우에만 변경 가능합니다. 만약 여러분이 문자의 배열이 일정하지 않고 그 배열로부터'String' 객체를 생성한다면 배열을 수정할 수 있고 불변의'String' 객체도 변경 될 것입니다. –

+0

나는 그것을 지금 깨달았다. 감사! –

+2

@BoPersson 저는 속마귀가 옳다고 생각하지 않습니다. 그것은 부분을 담당하지만 여기에도 다른 것들이 있습니다. – NathanOliver

답변

1

이다. 포인터와 배열 생성자는 모두 s에 정확히 일치하는 것으로 간주되므로 모호함이 있지만 배열 생성자가 템플릿이기 때문에 포인터 생성자와 일치하는 것이 적을 것으로 간주됩니다. explicit을 제거하더라도 포인터 과부하가 여전히 선택됩니다. sString하지 않기 때문에

String string = s; 

explicit와 지금

중요합니까. 이것은 컴파일러가이를 암시 적으로 하나로 변환하여 정확히 일치하므로 배열 생성자를 선택하고 암시 적 변환에서 명시 적 생성자로만 사용할 수있는 생성자를 사용할 수 없음을 의미합니다.

+0

그래서'explicit'이 없으면 포인터 오버로드는 템플릿 화되지 않았기 때문에 호출됩니다. –

+1

@AnirbanSarkar 예, 템플릿의 우선 순위가 낮기 때문에 포인터 생성자가 우선합니다. – NathanOliver

+0

설명해 주셔서 감사합니다. –

관련 문제