2017-03-07 13 views
3

내가, 포인터, 참조 또는 일정한 기준이 setter 함수로 전달 될 수있다 할 노력하고 있어요 : 나는 것을 보았다함수 호출 모호성

class A{ 
    std::string * p; 
    std::string st; 

    public: 
    A():p(0) 
    {} 
    A& setS(const std::string& s){ 
     std::cout<<"called with const std::string&\n"; 
     st = s; 
     p = &st; 
     return *this; 
    } 
    A& setS(std::string& s) { 
     std::cout<<"called with std::string&\n"; 
     p = &s; 
     return *this; 
    } 
    A& setS(std::string* s) { 
     std::cout<<"called with std::string*\n"; 
     p = s; 
     return *this; 
    } 
}; 

int main(){ 
    std::string s; 
    A a; 
    a.setS(std::move(s)) //const std::string& 
    .setS("")   //const std::string& 
    .setS(s)   //std::string& 
    .setS(0);   //std::string* 
    //if std::string* version is not defined, 
    //setS(0) calls the const std::string& version and throws exception 
    return 0; 
} 

그러나 , 포인터 버전이 없다면, setS(0)은 버전의 const std::string& 버전을 호출합니다.

포인터와 참조 버전간에 또는 다른 중요한 것들 사이에 모호성이 있습니까? 잘 정의되어 있고 모든 컴파일러에서 같은 방식으로 작동 할 것으로 예상됩니까?

+0

메신저 무슨 일이 일어나고 있는지 (null) 포인터에서 문자열을 만들 수 있고 그 임시는 const 참조에 바인딩됩니다. 이 경우에는 바람직하지 않지만, 이것은 나에게 "정상적인 행동"인 것으로 보입니다. – Borgleader

답변

3

모호성이 없습니다. 오버로드가 설정된 A& setS(std::string* s)이 있으면 setS(0)은 포인터 버전을 호출하고 0은 널 포인터입니다. 그것은 setS(nullptr)의 equivelent 일 것입니다. A& setS(std::string* s) 설정 과부하하지 않을 때는

다음 컴파일러는 0에서 임시 문자열을 구성하고 다음 const& 이후 A& setS(const std::string& s)에 임시로 결합 할 수 있음을 전달할 수있는 방법이 있는지 보인다. std::string은 단일 포인터로 구성 될 수 있으며 다시 0 null 포인터로 트레드합니다. 그래서 const& 함수에 전달 된 std::string 임시 null 포인터가 생성됩니다.

그러나 이것은 정의되지 않은 동작입니다. std::string의 생성자는 전달 된 포인터가 null로 끝나는 C 문자열이어야합니다. 그렇지 않은 경우 동작은 정의되지 않습니다.

0

setS 함수의 포인터 오버로드를 제거하면 const std::string& 버전을 호출하는 이유는 one of the std::string constructors입니다.

basic_string(const CharT* s, 
       const Allocator& alloc = Allocator()); 

는 그래서 0NULL로 처리하고 std::string가 구성 될 수있는에서 const char*로 해석되고있다. const&은 lvalue의 수명을 연장 할 수 있으므로 setS의 오버로드로 전달 될 수 있습니다.

+1

''NULL '은 보통'0'으로 확장되기 때문에'0'은 실제로''NULL''로 취급되지 않습니다. 그것은, 그러나, null 포인터로 취급되고있다. – Angew