我有一个带有模板化可调参数的函数,并将索引传递给它。在某些情况下,我希望静态传递该索引(我正在使用元组)。我认为通过使用模板化调用操作符并使用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 article和this one,但我很难适应我的用例。有任何想法吗?是否可以不修改呼叫站点?
答案 0 :(得分: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>
。
传递模板非类型参数很糟糕。避免它们。