2012-10-16 3 views
2

과부하 : (유형 U의) 파서가 "skp"라는 이름의 필드, 해당 필드를 사용을 제공하는 경우겉으로 모호한 템플릿 함수 내가이 우연히 때 해결하기 위해 노력 원래 문제가 <code>parse_impl</code> 버전을 선택하는 것이 었습니다

  • 을;
  • 그렇지 않은 경우 기본값을 사용하십시오.

는 다음 코드를 내놓았다 :

// This variant compiles for parsers requiring a skipper: 
template <typename I, typename U, typename A, 
      typename = typename std::enable_if< 
       not std::is_same< 
        typename std::remove_reference<U>::type::skipper_type, 
        qi::unused_type 
       >::value 
      >::type, 
      typename = void > // avoid redefinition (1 more overload not shown) 
bool parse_impl(I & start, I end, U && parser, A & attr) 
{ 
    // qi::space by default: 
    return qi::phrase_parse(start, end, parser, qi::space, attr); 
} 

// This variant compiles for parsers providing skipper via 'skp' member: 
template <typename I, typename U, typename A, 
      typename = typename std::enable_if< 
       not std::is_same< 
        typename std::remove_reference<U>::type::skipper_type, 
        qi::unused_type 
       >::value 
       && (sizeof(U::skp) != 0) 
      >::type, 
      typename = void, typename = void > // avoid redefinition 
bool parse_impl(I & start, I end, U && parser, A & attr) 
{ 
    // parser.skp is available: 
    return qi::phrase_parse(start, end, parser, parser.skp, attr); 
} 

이 같은 호출 사이트의 모양을

pr.is_ok = parse_impl(pr.position, input.cend(), parser, pr.attr); 

이가하지 않은 skp과 1을 갖는 유형에 대한 두라고 .

그리고 그것은 (gcc4.7에) 컴파일하지만 왜 이해가 안 : skp가있는 경우, 두 enable_if의 표현식이 true로 평가해야하며, 전화 (skipper_type 분명히 다음 unused_type 같지 않음) 모호해야합니다. 내가 어디서 잘못 본거야?

+0

[감소 된 테스트 케이스] (http://liveworkspace.org/code/5a6093ff1c940b48071231ec1d1d12bf) atleast는 모호하며, 내가 다른 것을 수행했는지 알 수 없습니다. 필자는 세 번째 과부하 인'skp '가 실제로 실제로 어떤 이유로 호출되지 않는다고 추측 할 수 있습니다. 어쩌면 테스트 인쇄 문을 그 안에 넣을 수 있습니까? 마지막으로 [this blog post] (http://rmartinho.github.com/2012/06/01/almost-static-if.html)와 [this] (http://stackoverflow.com/q/12654067/500104) question and [this] (http://stackoverflow.com/a/9154394/500104) 답변. :) – Xeo

+0

@ Xeo : 나는 그것을 마침내 찍었습니다. 실제로 차이가 있습니다 : 실제로 sizeof (NoRef :: skp)'(sizeof (U :: skp)! = 0)'에 있습니다. 'NoRef'는 마침내 모호함을 가져왔다! * 큰 도움과 링크를 주셔서 감사합니다! – vines

+0

아, 그래서 문제는 당신이 lvalue를 통과 할 때 (그리고 'U'가 참조로 추론 될 때), 당신은 SFINAE를 얻게된다는 것입니다. :) 그리고 참으로 [그게 문제 야.] (http://liveworkspace.org/code/f35132f82751e262fd6a64515e11bebd). – Xeo

답변

1

여기서 설명하는 문제는 단지 U::skp을 사용할 때 U이 참조 유형 (즉, 왼쪽 값 파서를 전달할 때)으로 추론 될 수 있다는 점입니다. 이 경우 SFINAE가 발생합니다. 참조 유형은 중첩 된 이 아니므로입니다.

해결 방법은 U에서 std::remove_reference이라는 참조를 제거하여 (sizeof(std::remove_reference<T>::type::skp) != 0)이되도록하는 것입니다. 여기에 typename은 필요하지 않습니다. ::skptype이 typename이어야 함을 나타냅니다.