2016-10-09 12 views
3

나는 pass template function as template argument을 알고 있었기 때문에 비슷한 방식으로 변수 템플릿을 전달하기 위해 고심하고 있습니다. 이 컴파일하면람다를 통해 변수 템플릿을 함수로 전달할 수 있습니까?

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \ 
                {return name<decltype(args)...>;} 

//testing 
template <typename T> 
bool value = std::is_fundamental<T>::value; 

template <typename Hax> 
void print_bool(Hax h) 
{ 
    std::cout << h(int{}) << std::endl; // no error, wrong output 
    //std::cout << h(int{}, float{}) << std::endl; // error, good 
} 

int main() 
{ 
    print_bool(PASS_VARIABLE_TEMPLATE(value)); //prints 0 instead of 1 
} 

Demo

, 왜 출력이 잘못 : 여기

내가 뭘하려 최소한의 예입니다?

+0

참조가 충분합니까? – lorro

+0

@lorro 오, 어리석은 나를, 부패를 잊어 버렸습니다! 그러나 다른 한편으로는 참조/포인터 검사를 파괴 할 것입니다 ...이 경우도 검사 할 수 있어야합니다 :'int b; int & ref = a; h (ref); // 타입은 int &'당신은 '#DEFINE의 PASS_VARIABLE_TEMPLATE (이름) [= 더미 nullptr] (자동 && 인수)와 예상되는 결과를 얻을 수 – xinaiz

+0

\t { \t \t 반환 이름 <유형 이름 표준 : remove_reference :: 유형>; \t}' –

답변

1
template<class T>struct tag_t{using type=T; constexpr tag_t(){}}; 
template<class Tag>using tagged_type=typename Tag::type; 
template<class T>constexpr tag_t<T> tag{}; 

이러한 도움말은 유형을 값으로 전달하고 압축을 풉니 다. print_bool 내부

#define PASS_VARIABLE_TEMPLATE(name) [](auto...args) \ 
               {return name<tagged_type<decltype(args)>...>;} 

은 당신이 할 :

std::cout << h(tag<int>) << std::endl; 

확실하지 당신이 dummy=nullptr 일을하는 이유.

tag은 템플릿을 변형 할 수 있습니다.

+3

'dummy'는 non-capturing lambda (질문에 게시 된 링크에서 허용 된 답변을 확인하십시오)와 함께 GCC 버그로 인한 것입니다. Btw, 좋은 해결책. – xinaiz

3

코드의 주된 문제는 람다가 인수를 받아들이 전달 참조을 사용하기 때문에 decltypervalue 참조 (int&&)로 인수를 추론이다. std::is_fundamental베어 유형과 잘 작동합니다.

특정 스 니펫의 경우 올바른 해결책은 remove the reference입니다.

#define PASS_VARIABLE_TEMPLATE(name) \ 
    [dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;} 

이제 작동합니다. :-)이 Live On Coliru


A가 약간 더 이상 일반적인 방법에 추가로 remove cv 예선 될 것입니다 참조하십시오. 결국, 당신은 사용할 수 있습니다 std::decay

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \ 
{return name<std::decay_t<decltype(args)>...>;}