2017-09-12 21 views
0

템플릿 호출 가능 인수를 사용하는 함수가 있는데이 함수에 인덱스를 전달합니다. 어떤 경우에는 인덱스를 정적으로 전달하고 싶습니다 (저는 튜플을 가지고 작업하고 있습니다). 필자는 템플리트 된 호출 연산자와 함께 호출 가능한 객체를 전달하고 SFINAE를 사용하여 이것이 가능해야한다고 생각했습니다.SFINAE를 사용하여 템플릿 호출 연산자에 디스패치하는 방법

struct A { 
    template< size_t I > 
    void operator()(int x) 
    { 
     cout << "A " << x << " " << I << endl; 
    } 
}; 

struct B { 
    void operator()(int x, int i) 
    { 
     cout << "B " << x << " " << i << endl; 
    } 
}; 


template< 
    typename F, 
    size_t I = 0 
> 
inline 
void 
call(int x, F & fn) { 
    fn(x, I); 
} 


int main() 
{ 
    A a;   
    B b; 

    call(2, b); 
    call< B, 3 >(2, b); 

    call(1, a); // no match for call to '(A) (int&, long unsigned int)' 

    return 0; 
} 

그래서 내가 SFINAE를 호출 기능에 과부하 사용하여 바로 호출을 선택하려고 : 처음에는

이 뭔가 보이는

template< 
    typename F, 
    size_t I = 0 
> 
inline 
typename std::enable_if< /* I've tried all kinds of things here */ >::type 
call(int x, F & fn) { 
    fn<I>(x); 
} 

을하지만 알아낼 수 없습니다 F가 하나의 템플릿 매개 변수와 int 인수로 호출 가능한지 여부를 감지하는 유형 특성 this articlethis one을 참조했지만 사용 사례에 맞게 수정하는 데 문제가 있습니다. 어떤 아이디어? 전화 사이트를 수정하지 않고도 가능합니까?

+2

게으르다. 템플릿이 아닌 형식 인수로 사용하지 않고()에 대한 인수로 정수 상수를 쓰는 것을 고려하십시오. 템플릿 비 형식 인수가 명시 적으로 전달되었습니다 ... 음, 빨아들입니다. – Yakk

+0

은 흥미로운 아이디어처럼 들리지만 실제로 그 코드가 무엇인지에 대해서는 완전히 분명합니다. 궁극적으로, 내가하는 일은'std :: get'을 호출하는 것과 호환되어야한다. 그래서 나는 명백한 템플릿 non type 인자를 고수했다. – Ian

답변

2
struct A { 
    template< std::size_t I > 
    void operator()(int x, std::integral_constant<std::size_t, I> i) { 
    cout << "A " << x << " " << I << endl; 
    } 
}; 

대신 사용하십시오. 표준 SFINAE 테스트가 작동하며 템플릿이 아닌 형식 인수를 전달하지 않습니다.

C++ 14 컴파일러에서는 std::get<i>을 사용할 수 있습니다. C++ 11 컴파일러에서는 std::get<I> 또는 std::get<decltype(i)::value>을 사용할 수 있습니다.

전달 템플릿 비 형식 인수가 빠릅니다. 그들을 피하십시오.

+0

그래, 그게 훨씬 더 나은 해결책 같아.하지만 여전히 "전화를 걸지 않아."라는 오류가 발생합니다. 'long unsigned int'는'integral_constant '로 변환되지 않습니까? http://coliru.stacked-crooked.com/a/e56d8be9bfe754f7 – Ian

+0

@ian 정수는 정수가 아닌 값을 전달합니다. 유형의 이름을 지정하고 구성하십시오. 'std :: integral_constant {}'. – Yakk

+0

오른쪽 : 물론 : P – Ian