如何使用 SFINAE 调度到模板化呼叫操作员

How to dispatch to templated call operator using 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;
}

所以我尝试重载调用函数,select 使用 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 article and this one 但无法将它们适应我的用例。有任何想法吗?不修改调用站点是否可以?

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>.

传递模板非类型参数很糟糕。避开它们。