2014-09-19 1 views
1

두 개의 다른 구조체, Foo 및 Bar에서 상속하는 Baz 구조체와 같은 구조를 가지고 있습니다."오버로드 된 함수에 대한 모호한 호출"

두 가지 방법이 있는데, 하나는 Foo 매개 변수이고 다른 하나는 Baz 매개 변수입니다.

struct Foo 
{ 
}; 

struct Bar 
{ 
}; 

struct Baz : Foo, Bar 
{ 
    virtual void something(const Foo& foo) 
    { 
    }; 

    virtual void something(const Bar& bar) 
    { 
    }; 
}; 

나는이

Baz baz; 
baz.something(baz); 

과 같이 호출 그리고 당연히 나는 내 코드는 내가 그것을 바즈의 인스턴스를 전달하면 내가 부르고 기능을하는 아는에 문제가 있습니다. 나는 오버로드 된 함수에 "모호한 호출"을 받는다.

Baz baz; 
baz.something((Bar)baz); 

내가 문제를 해결하기 위해 푸 또는 바 내 바즈 전송할 수 있습니다 알고

... ...하지만이 디자인 문제를 다루는 또 다른 방법은 무엇입니까?

전달되는 개체가 Bar 유형이 아닌 경우에만 Foo 메서드를 호출하고 싶습니다.

편집 :이 C 번호는 (은하지 않은) 인 경우

은 아마 템플릿 where 절을 사용하여이 문제를 해결 할 수있다.

+0

글쎄, 무엇을 정확하게 당신이 할 컴파일러 원하는거야 당신은 아마이 의미 이 경우에는? (그리고 왜이 지구상에서이 일을하고 있습니까?)'바즈 (Baz) '는'푸 (Foo)'와'바 (Bar) '로 전환 할 수 있습니다. 어떤 방식 으로든 컴파일러에게 알려야 할 필요가있을 것입니다. C++ 11에서 삭제 된'Baz'를'Foo'로 명시 적으로 변환 할 수 있습니다. 이것은 사용할 수 없다는 것을 의미합니다. 또는'Bar' 버전을 호출하는'Baz'에'something'을 구현하십시오 ... 아니면 단순히'something'에 의해 호출되는'Baz'를 포함하여 각 클래스에 대해'DoSomething' 가상 함수를 구현하십시오. –

+0

왜 이러한 메서드에 동일한 이름을 지정해야합니까? 다른 이름을 사용하면 모호성을 피할 수 있습니다. 나는이 이상한 코드를 만들 필요성을 이해할 수 없다. –

+0

[** 끔찍한 ** **] (http://ideone.com/HeFsDS)와 같은 것을 의미하지는 마십시오. – WhozCraig

답변

2

먼저 사용했던 캐스트가 임시 개체를 생성합니다.

baz.something(static_cast<Bar&>(baz)); 

그리고 귀하의 질문에 대답하기 위해,이에 대한 SFINAE을 사용할 수 있어야한다 :

struct Baz : Foo, Bar 
{ 
    virtual void something(const Bar &bar) 
    { /* ... */ } 

    template < 
    class T, 
    class = typename std::enable_if< 
     std::is_convertible<const T&, const Foo&>::value && 
     !std::is_convertible<const T&, const Bar&>::value 
    >::type 
    > 
    void something (const T &foo) 
    { something_impl(static_cast<const Foo&>(foo)); } 

private: 
    virtual void something_impl(const Foo &foo) 
    { /* ... */ } 
}; 

Live example

관련 문제