2014-11-19 3 views
5

나는 내가 제대로 이해할 수 없거나 올바르게 해결할 방법을 찾지 못했습니다. 내가 성취하고자하는 것은 상대적으로 단순 해 보입니다. 몇 가지 데이터를 비교하고 싶습니다. 나는 예를 위해서 튜플을 사용하고가변성 템플릿 추출

std::tuple<const char *, int, const char *, int> my_data = 
    std::make_tuple("hello", 13, "world", 37); 
// Now I want to compare my_data againt some known value. 
assert(Test::entry(my_data, "hello", 13, "world", 37)); 

: 설명하는

가장 좋은 방법은 코드 줄 것입니다. 저의 경우, 그 데이터는 메시지 객체에서 가져오고 operator>>을 사용하여 추출됩니다. 그러나 이것은 문제와 관련이 없습니다.

다음은 문제를 설명하기위한 최소한의 코드입니다.

#include <cstring> 
using MyTuple = std::tuple<const char *, int, const char *, int>; 

namespace Test 
{ 

    // called when we are done                                         
    bool extract(MyTuple source) 
    { 
    return true; 
    } 

    template<typename T, 
      typename ...Content> 
    bool extract(MyTuple source, T data, Content... content) 
    { 
    if (std::is_same<const char *, T>::value) 
     assert(0); // why ? :(                                         
    std::cout << "Generic: " << data << std::endl; 
    return extract(source, content...); 
    } 

    template<typename ...Content> 
    bool extract(MyTuple source, const char *str, Content... content) 
    { 
    std::cout << "Overloaded: " << str << std::endl; 
    return extract(source, content...); 
    } 

    template<typename ...Content> 
    bool entry(const std::tuple<const char *, int, const char *, int> &data, 
      Content... content) 
    { 
    return extract(data, content...); 
    } 

}; 

나는 normaly extract() 기능에 comparaison을 수행 할 것이나, 간단한 예제를 유지하기 위해, 나는 그들을 제거했습니다.

내가 원하는 것은 적절한 파견입니다.

  1. 그러나 const char *
  2. 일반

,이 테스트의 출력 const char *

  • 일반
  • 과부하에 대한 오버로드 : 예제를 바탕으로이 순서가 있어야한다 전화 나의 이해는 프로그램 :

    1. 오버로드 : hello
    2. 일반 : 13
    3. Assertion failed. std::is_same 테스트는 assert을 트리거합니다.

    내가 발견 한 것은 일반 오버로드가 한 번 호출 된 후에 const char * 오버로드가 호출되지 않는다는 것입니다.

    내가 누락 되었습니까?

    EDIT : 일반 함수 이전에 const char * 오버로드를 정의하면이 또한 컴파일되지 않습니다.

  • +0

    당신이 원하는 튜플의 타입을 이미 알고있을 때'std :: make_tuple'을 사용하는 것은 약간 어리석은 일입니다. -'make_tuple'의 전체 포인트는 초기화 자의 타입으로부터 튜플 타입을 추론하는 것입니다. 당신은 단순히'std :: tuple my_data { "hello", 13, "world", 37};' – Casey

    +0

    @Casey 그래도 이것을 사용할 수 있습니다. 문제. 내 데이터 소스는 물건을 추출 할 수있는 소켓입니다. – Xaqq

    답변

    3

    일반 기능 전에 const char * 오버로드를 정의하면 컴파일도되지 않습니다.

    선언은 충분합니다 :

    template <typename... Content> 
    bool extract(MyTuple source, const char *str, Content... content); // <- here 
    
    template <typename T, typename... Content> 
    bool extract(MyTuple source, T data, Content... content) 
    { 
        std::cout << "Generic: " << data << std::endl; 
        return extract(source, content...); 
    } 
    
    template <typename... Content> 
    bool extract(MyTuple source, const char *str, Content... content) 
    { 
        std::cout << "Overloaded: " << str << std::endl; 
        return extract(source, content...); 
    } 
    

    이유는 무엇입니까?

    const char* 복용 과부하 전에 선언없이 특정 이름 조회 중에 보이지 않는다. 이것에 대한 예외 중 일부는 comments below에서 찾을 수 있습니다.

    +0

    고마워. 이제는 모두 의미가 있습니다. 이것은 또한 왜 다른 함수가 사용 가능하지 않았던지를 알아 내기 위해'std :: enable_if' 함수를 숨기려고하면 컴파일 타임 오류가 발생하는 이유가 설명 될 것입니다. – Xaqq

    +0

    'const char *'오버로드를 찾을 수없는 이유는 정의 문맥을 사용하는 정규화되지 않은 조회 나 ADL이 사용할 수 없기 때문입니다. MyTuple이'Test' 네임 스페이스에서 타입을 명명했다면, 인스턴스화 컨텍스트를 사용하는 ADL은 이전 선언없이 'const char *'오버로드를 찾을 수있었습니다. –

    +0

    @ T.C. 나는 내가 이해할 것이라고 생각하지 않는다. 'Test' 네임 스페이스 안에'typedef'라는'MyTuple'과 같은 의미입니까? 예를 들어 주시겠습니까? – Xaqq

    관련 문제