2017-12-17 30 views
2

을 사용 걸릴 수 있습니다 감지 . 다음 과부하 세트 예컨대고려 다음 코드를 인수의 최대 숫자를 함수 템플릿 메타 프로그래밍

:

void f(int, int); // f called with 2 ints compiles 
void f(int, int, int); // f called with 3 ints compiles 
void f(int, char, int, double); // f called with 4 ints compiles 
void f(int, std::string, int, int, int); // f called with 5 ints does not compile 

결과 :

maximum_number_of_arguments<int>(f) 

4를 반환한다.

필자는 함수가 취할 수있는 제한된 수의 매개 변수 (예 : 256)를 수정하고 모든 가능성을 테스트하고 컴파일에 실패하지 않는 호출을 추적하는 방법을 추측합니다. 템플릿/contexpr 메타 프로그래밍을 사용하여이를 수행하는 방법은 무엇입니까?

편집 :

#include <iostream> 

struct functor 
{ 
    void operator()(int) {std::cout << "int" << std::endl;} 
    void operator()(int, int) {std::cout << "int, int" << std::endl;} 
    void operator()(int, int, int) {std::cout << "int, int, int" << std::endl;} 
}; 

template <class F> 
void caller(F&& f) 
{ 
    std::forward<F>(f)(1); 
    std::forward<F>(f)(1, 2); 
    std::forward<F>(f)(1, 2, 3); 
} 

int main(int argc, char* argv[]) 
{ 
    functor f; 
    caller(f); 
    return 0; 
} 
+7

'printf'에 대한 대답은 무엇이되어야합니까? –

+3

또는'template void foo (T ...)' – Barry

+3

"최대 인수 수를 찾을 수있는 함수를 원합니다 ...."- 이유가 무엇입니까? 유스 케이스 란 무엇입니까? 재미 있지는 않지만 x-y 문제처럼 냄새가납니다. –

답변

3

당신이 요구하는 것은 정확히 사소한되지 않습니다 : 우리가 함수에 과부하 세트를 전달할 수 없다는 사실에 의견에 대답하려면 (f 내 예는 아마도 최고의되지 않습니다) ...

경우 ... 혼자 함수 또는 공통 식별자 기능의 집합, 다른 유형의 통화를 제외한를 호출하는 데 사용할 수있는 정수의 최대 수에 관심이

내 말은 ... 버전 std::string 제외 될 받도록 때문에 f() 기능

void f(int, int); 
void f(int, char, int); 
void f(int, std::string, int, int, int); // excluded by std::string 

의 다음 세트에 대한 검사가 3를 받아야하는 경우 ... A를

음 ... 매크로 (그래서 내 솔루션은 고유 악) 심볼 전용 체크 구조체를 정의하는

setMaxStruct(f); 

당신은 정수 인수의 최대 수를 얻을 수 있습니다 (설정 가능한과를하지만 최대 기본값)로 뭔가를 쓰기

std::cout << "--- f: " << getMaxArgsFor_f<int>::value << std::endl; 

다음은 전체 작업 예를

#include <utility> 
#include <iostream> 
#include <type_traits> 

template <typename T, std::size_t> 
using typer = T; 

#define setMaxStruct(func)          \ 
                    \ 
template <typename Type, std::size_t MaxArgs = 64U>    \ 
struct getMaxArgsFor_ ## func          \ 
{                \ 
    template <typename, std::size_t ...>       \ 
    static std::false_type isCallable (...);      \ 
                    \ 
    template <typename T, std::size_t ... Is>      \ 
    static auto isCallable (int)         \ 
     -> decltype(func(std::declval<typer<T, Is>>()...),   \ 
        std::true_type{});       \ 
                    \ 
    template <typename T, std::size_t ... Is>      \ 
    static constexpr bool getMaxTH3        \ 
     (std::index_sequence<Is...> const &)      \ 
    { return decltype(isCallable<T, Is...>(0))::value; }   \ 
                    \ 
    template <typename T, std::size_t I>       \ 
    static constexpr bool getMaxTH2()        \ 
    { return getMaxTH3<T>(std::make_index_sequence<I>{}); }  \ 
                    \ 
    template <typename T, std::size_t ... Is>      \ 
    static constexpr std::size_t getMaxTH1       \ 
     (std::index_sequence<Is...> const &)      \ 
    {                \ 
     std::size_t ret (-1);          \ 
                    \ 
     ((ret = getMaxTH2<T, Is>() ? Is : ret), ...);    \ 
                    \ 
     return ret;             \ 
    }                \ 
                    \ 
    template <typename T, std::size_t MaxAs>      \ 
    static constexpr std::size_t getMaxT()      \ 
    { return getMaxTH1<T>(std::make_index_sequence<MaxAs>{}); } \ 
                    \ 
    static constexpr std::size_t value = getMaxT<Type, MaxArgs>(); \ 
} 

void f(int, int); 
void f(int, int, int); 
void f(int, char, int, double); 
void f(int, std::string, int, int, int); 

template <typename ... Args> 
void h (Args ... args); 

setMaxStruct(f); 
setMaxStruct(g); 
setMaxStruct(h); 

int main() 
{ 
    std::cout << "--- f: " << getMaxArgsFor_f<int>::value << std::endl; 
    std::cout << "--- g: " << getMaxArgsFor_g<int>::value << std::endl; 
    std::cout << "--- h: " << getMaxArgsFor_h<int>::value << std::endl; 
} 

입니다 다음 당신은 당신이 size_t(-1) (g()가 정의되지 않은) 얻을 h()에서 당신이 63 (최대 값을 얻을 g에서, 4을 얻을 f에서 해당 사항을 준수 마이너스 1).