2017-12-19 6 views
3

다음 코드를 고려하십시오void_t와 가변 템플릿을 섞어서 사용합니까?

template <class F, class... Args, class = std::void_t<>> 
struct is_invokable 
: std::false_type {}; 
template <class F, class... Args> 
struct is_invokable<F, Args..., std::void_t<std::invoke_result_t<F, Args...>>> 
: std::true_type {}; 

목표는 유형 F의 호출 유형 Args...의 인수로 호출 가능한 상태인지의 구분 할 수있는 특성을 가지고있다.

error: parameter pack 'Args' must be at the end of the template parameter list 

는 C++ 17이에서 할 수있는 (우아한) 방법은 무엇입니까 : 때문에

그러나 컴파일에 실패?

+4

음, 같은 Args...

뭔가를 포장하는 도우미 struct (is_invokable_h)와 std::tuple의 사용을 제안한다 ? 거기에 넣어. – Barry

+0

허. 나는 그 종류가 팩이 최종 위치에 있어야한다는 것을 깨닫지 못했습니다. 함수가 기본 인수를 주거나 추론 할 수없는 경우 함수는 그렇지 않습니다. –

답변

6
namespace details { 
    template <class F, class, class... Args> 
    struct is_invokable : std::false_type {}; 
    template <class F, class... Args> 
    struct is_invokable<F, std::void_t<std::invoke_result_t<F, Args...>>, Args...> 
    : std::true_type {}; 
} 
template <class F, class... Args> 
using is_invokable=typename ::details::is_invokable<F, void, Args...>::type; 
1

는 당신이`void`을 넣을 수 밖에 다른 말에 비해

#include <type_traits> 
#include <utility> 

template <typename, typename, typename = void> 
struct is_invokable_h : std::false_type 
{}; 

template <typename F, typename ... Args> 
struct is_invokable_h<F, std::tuple<Args...>, 
         std::void_t<std::invoke_result_t<F, Args...>>> 
    : std::true_type 
{}; 

template <typename F, typename ... Args> 
struct is_invokable : is_invokable_h<F, std::tuple<Args...>> 
{}; 

int foo (int) 
{ return 0; } 

int main() 
{ 
    static_assert(true == is_invokable<decltype(foo), int>{}); 
    static_assert(false == is_invokable<decltype(foo), int, int>{}); 
} 
+2

또는 C++에서 도입 한 [std :: is_invocable] (http://en.cppreference.com/w/cpp/types/is_invocable) 17. –

+0

맞습니다 : 또는'std :: is_invocable'. 하지만 내 의도는 템플릿 variadic 목록 후에 기본 템플릿 유형의 문제를 무시할 수있는 방법을 보여줍니다. – max66

관련 문제