2010-07-06 6 views
1

이 방법은 가능하지 않지만 템플릿 프로그래밍 마법을 사용하여 입력에 따라 다른 반환 값을 갖는 함수를 정의하는 방법이 있습니까? 잠재적컴파일 타임에 템플릿 함수 결과의 유형을 결정 하시겠습니까?

는 :

template<typename resultType> 
resultType GetResult(const std::string &key); // where the value of key may change resultType 

template<typename keyType, typename resultType> 
resultType GetResult(keyType key); 

지금, 나는 위가 올바르지 않은 것을 알고있다. 첫 번째 함수를 사용하려면 함수를 호출하기 전에 resultType이 무엇인지 알아야합니다. 그러나, 나는 많은 "불가능한"것들이 간접적 인 또 다른 계층 (또는 두 가지)으로 가능해질 수 있다는 것을 배웠다. 나는 그것을 할 올바른 방법을 찾을 수없는 것 같습니다.

두 번째 옵션은 내 두뇌를 간질입니다. 문자열을 유형 (또는 무엇이든)에 매핑하는 다른 도우미 객체를 정의 할 수 있어야한다고 생각한 다음 해당 템플릿 매개 변수를 사용하여 GetResult을 호출하는 컴파일 시간 결과를 얻었습니다.

편집 : resultType에 사용 된 유형이 서로 관련이 없다고 가정합니다. "실제"유형에 대해 테스트 할 수있는 인터페이스가 없습니다 (어쩌면 intMyClass * 일 수 있음).

편집 2 : 실제 사용에서는 위젯, 가젯 등의 컬렉션이 포함 된 제 3 자 개체가 있습니다. 문자열 ID (형식이 접두사로 붙어 있기 때문에 편리함) 그러나 문자열을 구문 분석해야 "collectionInstance.getWidget (id)"를 호출해야한다는 것을 알 수 있습니다. 내 계획은 이러한 내부 개체를 얻는 방법을 지능적으로 알 수있는 씬 개체를 작성하는 것이 었습니다.

답변

2

아니오 컴파일 타임에 정의 된 반환 유형은 런타임 값에 따라 달라질 수 없습니다.

boost :: variant 또는 boost :: any를 반환 할 수 있습니다.

2

두 번째 예제에서 이러한 유형을 매핑하는 도우미 메타 기능이 필요합니다. typename helper<keyType>::type이 반환 유형이되고 keyType 템플릿 매개 변수가 제거됩니다. 당신의 도우미 메타 기능은 템플릿 매개 변수에 따라 type typedef를 생성해야합니다. boost :: mpl :: map은이 작업을위한 유용한 유틸리티이고, 아마도 BOOST_STRONG_TYPEDEF는 std :: string을 기반으로 다른 유형을 정의 할 수 있습니다.

0

편집 내용에 따라 원하는 것은 원하지 않는 내용입니다. 당신이 필요로하는 것은 :

1) X, Y, Z 관련없는 유형들 사이에 어떤 유형의 변수도 저장하는 방법. 2) 변수를 얻기 위해 호출 할 함수를 찾기 위해 문자열을 구문 분석하는 방법.

첫 번째 문제는 boost :: variant로 해결할 수 있습니다.

두 번째는 두 부분으로 해결할 수 있습니다. 첫 번째는 실제로 적절한 호출을 수행 할 함수 또는 객체를 반환하는 구문 분석 루틴입니다. 두 번째는이 호출을 수행하고 변형에 할당하는 객체 또는 함수 집합입니다. 따라서 당신과 같이 뭔가 끝장 : 당신이 실제로 문자열의 나머지 부분에서 형식 정보를 분리해야하는 경우 또는 다른 기능을해야합니다 위해 다음 get_call가 수행해야합니다

boost::variant<X,Y,Z> get_result(std::string stuff) 
{ 
    return parser::instance().get_call(stuff).make_call(stuff); 
} 

그 문자열을 두 조각으로 분리하여 위의 호출에 제공합니다.

+0

나는이 대답에 대한 응답으로 질문을 업데이트했다. 편집 2를 참조하십시오. – moswald

+0

boost :: variant/QVariant/boost :: any를 사용하지 않기를 바랬습니다. 따라서 런타임 데이터를 기반으로 함수의 결과를 변경하는 방법을 묻는 것입니다. 오 잘. 네가 아마 이것에 대해 맞는 것 같아. miked 옵션을 살펴 보겠다.하지만 실제로 사용되는 것을 보게 될 것이다. – moswald

0

캐스트 연산자로 해킹 할 수 있습니다.나는 이것이 좋은 프로그래밍 실습이라는 주장을하지는 않지만, 실행 가능하다. :

template <typename keyType> 
    class GetResult 
    { 
     keyType mkey; 

     GetResult(keyType key) : mkey(key) {} 

     template <typename resultType> 
     operator resultType() 
     { 
      //do stuff here that returns result type 
     } 
    } 
+0

이것이 어떻게 작동하는지 나는 볼 수 없습니다. 호출되는 변환 연산자는 사용되는 표현식과 관련된 유형 (즉, 어떤 변환 연산자를 사용할지 지정해야 함), 컴파일 타임에 해석되며 문자열과 같은 런타임 값이 아닌 형식에 따라 달라집니다. – Staffan

관련 문제