2012-07-27 7 views
2

이것이 sfinae와 관련이 있는지 또는 템플릿 기능과 관련이 있는지 확실하지 않습니다.C++ 11 스타일 SFINAE 및 템플릿 인스턴스화에 대한 기능 가시성

struct S; 

template <typename T> 
inline auto f(S& s, T const& t) 
    -> decltype(t.f(s), void()) 
{ 
    t.f(s); 
} 

struct S 
{ 
    template <typename T> 
    auto f(T const& t) 
     -> decltype(f(*this, t), void()) 
    { 
     f(*this, t); // <------------------------------------------- HERE 
    } 
}; 

struct pass 
{ 
    void f(S&) const 
    { 
     //... 
    } 
}; 

struct fail 
{ 
}; 

int main() 
{ 
    S s; 
    s.f(pass()); // should compile fine 
    //s.f(fail()); // should fail to compile due to absence of f from S 
    return 0; 
} 
: 나는 다시 또 다른 유형의 멤버 함수의 실존에 따라 활성화/비활성화되어 해당하는 무료 기능의 유무에 따라 멤버 함수를 활성화/비활성화 할 수 sfinae를 사용하려고 시도하고, 모든 사용 방법은 here 설명 분명히 위의 f 세계가 오버로드 확인을 위해 고려되지 않음을 의미합니다

error: no matching function for call to 'S::f(S&, const pass&)'
note: candidate is:
note: template decltype ((f((* this), t), void())) S::f(const T&)
note: template argument deduction/substitution failed:
note: candidate expects 1 argument, 2 provided

:

그러나 GCC 4.7.1는 화살표로 표시된 라인에 저이 있습니다.

왜 그런가요? 그렇게하려면 어떻게해야합니까?

왜 두 줄 위의 오류가 있습니까? f이 비슷한 방식으로 decltype에 사용 된 이유는 무엇입니까? @ n.m으로

UPDATE

. 서명이 다른 경우에도 멤버 함수가 완전히 그림자없는 함수라고 했으므로에 대한 ADL을 깨지 않는 해결 방법이 있습니다 (@n.m에 의해 제안 된 전체 이름 자격과 달리). 자유 함수 (f_dispatcher)를 만들면 아무도 (detail)를 보지 않고 S::f 안에 이름을 지정할 수 있습니다. ADL f 무료 그 함수 호출 및하자과 같이,이 이후에서 알아서 :

struct S; 

template <typename T> 
inline auto f(S& s, T const& t) 
    -> decltype(t.f(s), void()) 
{ 
    t.f(s); 
} 

namespace detail 
{ 
    template <typename T> 
    inline auto f_dispatcher(S& s, T const& t) 
     -> decltype(f(s, t), void()) 
    { 
     f(s, t); 
    } 
} 

struct S 
{ 
    template <typename T> 
    auto f(T const& t) 
     -> decltype(detail::f_dispatcher(*this, t), void()) 
    { 
     detail::f_dispatcher(*this, t); 
    } 
}; 

struct pass 
{ 
    void f(S&) const 
    { 
     //... 
    } 
}; 

struct fail 
{ 
}; 

int main() 
{ 
    S s; 
    s.f(pass()); // compiles fine 
    //s.f(fail()); // fails to compile due to absence of f from S 
    return 0; 
} 
+0

'S :: f' 내부에서 using 선언문을 사용할 수 없습니까? – dyp

+0

@dyp, 할 수는 있지만 후행 형식에서는 표시되지 않습니다. –

+0

trailing-return-type은 선언의 일부이므로 내부에서 이름을 조회하면 해당 선언의 일부가 검색되지 않습니다. – dyp

답변

6

이 SFINAE 또는 템플릿 또는 C++ 11 ADL과는 아무 상관이 없습니다.

회원 섀도우 유형에 관계없이 모든 이름이 같은 비회원입니다. f 회원이있는 경우 규정 된 이름 (예 : ::f)을 사용하지 않는 한 f이 아닌 비회원은 참조 할 수 없습니다.

그냥 ::f(*this, t);을 사용하십시오.

+0

Whoa, 분명히 나는 ​​이전에 같은 이름을 가진 구성원 1 내부에서 자유로운 함수를 사용해야했습니다. 당신은 정말로 옳습니다. 하지만 난 여기에 자격을 얻은 이름을 사용할 수 없어요. –

+0

@dataRodríguez-dribeas는'decltype' 내부에서 사용에 영향을 미치지 않습니다. –

+0

@ DavidRodríguez-dribeas 그럴 필요는 없다고 생각됩니다. 어쨌든 거기에서 볼 수 있습니다. –