我正在尝试编写一个函数,使得f<T>(args..)
返回类型为T
的第一个参数。
以下程序似乎总是选择第一个专业化版本,因此打印97
(ASCII代码为'a'
)。尽管第二个不需要将char
转换为int
。有人可以解释一下这种行为吗?
我是SFINAE和元编程的新手。
#include <iostream>
using namespace std;
template <typename T, typename ...Ts>
T f(T a, Ts... args) {
return a;
}
template <typename R, typename T, typename ...Ts>
R f(typename enable_if<!is_same<R, T>::value, T>::type a, Ts... args) {
return f<R>(args...);
}
int main() {
cout << f<int>('a', 12);
}
答案 0 :(得分:7)
std::enable_if
的第二个模板参数应该是R
,这是您希望拥有的。
以下应该有效
template < typename R, typename T, typename ...Ts>
typename enable_if<!is_same<R, T>::value, R>::type f(T const& t, Ts&&... args)
// ^^^ ^^^^^^^^^^^
{
return f<R>(std::forward<Ts>(args)...); // forward the args further
}
答案 1 :(得分:4)
您的代码的第一个功能参数在非推论上下文中。 enable_if< expr, T >::type
无法推论T
。这是在“非推论上下文”中。
由于无法推论T
,foo<int>( 7 )
无法使用该重载;编译器不知道T
是什么。 foo<int,int>(7)
会称呼它。
template <typename R, typename T, typename ...Ts>
typename enable_if<!is_same<R, T>::value, R>::type f(T a, Ts... args)
现在T
处于推论上下文中。我们并没有试图推论R
(我们也不能从返回类型推论得出)。