我正在尝试编写一个函数,使f<T>(args..)
返回类型为T
的第一个参数。
以下程序似乎总是选择第一个专业化因此打印97
('a'
的ASCII代码)。虽然第二个不需要将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);
}
您的代码的第一个函数参数位于非推导的上下文中。 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
(我们也不能从返回类型推断)。
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
}