2017-01-19 3 views
2

함수 템플릿에 다음과 같은 문제가 있습니다. 나는이 같은 함수 템플릿이있는 경우, 어디 T 중 하나 ClassA 또는 ClassB 될 수 있습니다비 템플릿 함수에 매개 변수로 템플릿 유형을 전달하는 방법은 무엇입니까?

template<typename T, bool flag> 
void function(T& someT){ 
    if(flag){ /*If 'flag' is true, 'someT' MUST be of type ClassA*/ 
     nonTemplateFunction1(someT); 
    } 
    else{ /*Else 'someT' must be of type ClassB*/ 
     nonTemplateFunction2(someT); 
    } 
} 

그리고 다른 파일에 나는

void nonTemplateFunction1(ClassA& a){...} 

을 가지고 있고 또 다른 파일에 내가

void nonTemplateFunction2(ClassB& b){...} 

이제 함수 템플릿을 호출하면 컴파일시 오류가 발생합니다.

error: no matching member function for call to 'nonTemplateFunction2'

컴파일러가 예를 들어 ClassA 매개 변수로 nonTemplateFunction2에 대한 호출을 테스트하기 때문일 것입니다. 그러나 이것은 결코 일어날 수 없다 (나는 적어도 프로그래머인데, 이것을 돌봐 준다). 내 프로그램을 컴파일하려면 어떻게해야합니까? 가능한 해결책은 무엇입니까?

편집 :보다 정확한 오류 :

./tabledata.hh:371:9: error: no matching member function for call to 'bulk_insert' bi.bulk_insert(bl, aRel_Vec[j]);

../pax/bulk_insert_pax.hh:21:8: note: candidate function not viable: no known conversion from 'value_type' (aka 'NSM_Relation') to 'PAX_Relation &' for 2nd argument void bulk_insert(const BulkLoader& aBulkLoader, PAX_Relation& aRelation);

답변

1

당신은 런타임 결정에 시간 결정을 컴파일 혼합하고 있습니다. 컴파일러는 someT 유형을 알고 있지만 예 : if 분기는 삭제하지 않습니다. 기본적으로 처리 후에는 다음과 같습니다

void function(ClassA& someT){ 
    if(true){ 
     nonTemplateFunction1(someT); 
    } 
    // branch will be optimized away, but still 
    // exists 
    else{ 
     // so this is still erroneous code, even though it never runs 
     nonTemplateFunction2(someT); 
    } 
} 

그래서 하나가 preprocesing 동안 원치 않는 지점을 제거하거나 대신 참조의 포인터를 사용하거나 기능을 리팩토링하는 방법을 참조하십시오. 옵션이 무엇인지 모르겠다. 템플릿이 좋지 않지만, 어쩌면 #ifdef에 플래그를 전달할 수 있을까? C++ 17에서

+0

흠, 난을 통과해야처럼 보인다 내 T를 가리키는 포인터. 가장 좋아하는 솔루션이 아니지만 작동해야합니다. –

+0

@ N.Weber 가장 빠른 옵션이라고 생각합니다. –

0

당신은 (있는 그대로 당신의 예제 코드) 그렇게 if constexpr을 사용할 수 있습니다 :

class ClassA{}; 
class ClassB{}; 

void nonTemplateFunction1(ClassA&){} 
void nonTemplateFunction2(ClassB&){} 

template<typename T, bool flag> 
void function(T& someT){ 
    if constexpr (flag){ 
     nonTemplateFunction1(someT); 
    } 
    else{ 
     nonTemplateFunction2(someT); 
    } 
} 

int main() { 
    ClassA a; 
    function<ClassA, true>(a); 
} 

wandbox에를 참조하십시오.


C++ 11/14에서는 sfinae를 사용할 수 있습니다. 그것은 최소한의 작업 예를 들어 다음과 같습니다

#include<type_traits> 

class ClassA{}; 
class ClassB{}; 

void nonTemplateFunction1(ClassA&){} 
void nonTemplateFunction2(ClassB&){} 

template<typename T> 
std::enable_if_t<std::is_same<T, ClassA>::value> 
function(T& someT){ 
    nonTemplateFunction1(someT); 
} 

template<typename T> 
std::enable_if_t<std::is_same<T, ClassB>::value> 
function(T& someT){ 
    nonTemplateFunction2(someT); 
} 

int main() { 
    ClassA a; 
    function(a); 
} 
원하는과 유형에 대해 명시하지 않으려면이 사용할 수

:

template<typename T> 
auto function(T& someT) 
-> decltype(nonTemplateFunction1(someT), void()) { 
    nonTemplateFunction1(someT); 
} 

template<typename T> 
auto function(T& someT) 
-> decltype(nonTemplateFunction2(someT), void()) { 
    nonTemplateFunction2(someT); 
} 
관련 문제