首先我使用enable_if,我在下面编写的代码不会编译,但它在逻辑上似乎是正确的,但是当前的enable_if实现不会支持。
1
2 #include <iostream>
3 using namespace std;
4
5 template<int N>
6 struct S{
7 template<class T>
8 typename enable_if<N==1,T>::type
9 f(T t) {return 1;};
10
11 template<class T>
12 T
13 f(T t) {return 0;};
14 };
15
16 int main() {
17 S<1> s1;
18 S<2> s2;
19 cout << s1.f(99) <<" "<< s2.f(99) << endl;
20 return 0;
21 }
错误信息准确无误,并且精确指出了问题。
enable_if.cc19:20: error: call of overloaded ‘f(int)’ is ambiguous
enable_if.cc:9:3: error: no type named ‘type’ in
‘struct std::enable_if<false, int>’
这似乎只是设计不明确的问题,很容易纠正。为了解决这个问题,我可以编写部分专用类模板:
#include <iostream>
using namespace std;
template<int N> struct S{
template<class T>
T
f(T t) {return 0;};
};
template<> struct S<1>{
template<class T>
T
f(T t) {return 1;};
};
int main() {
S<1> s1;
S<2> s2;
cout << s1.f(99) <<" "<< s2.f(99) << endl;
return 0;
}
但是为了清洁和方便,首先要增强enable_if模板以支持错误代码所敦促的新功能?
s1
调用f时,可以使用在示例中返回1的更专业的那个。s2
调用f时,将使用返回0的一般,即使第一个失败。 答案 0 :(得分:2)
您可以通过以下方式解决问题:
enable_if
。例如:
#include <type_traits>
template<int N>
struct S
{
template <class T>
typename std::enable_if<N == 1 && std::is_same<T, T>::value, int>::type
f(T t) {return 1;}
template <class T>
typename std::enable_if<N != 1, T>::type
f(T t) {return 0;}
};
这是live example。
答案 1 :(得分:1)
首先,我怀疑你的代码中有拼写错误。启用if应该在T上进行参数化,以编译:{{1}}而不是typename enable_if<N==1,T>::type
只需使用第二个重载,如果也是反转条件则启用。它有效:
typename enable_if<N==1,int>::type
答案 2 :(得分:0)
你仍然可以在没有部分专业化的情况下完成,但是:
您必须确保只存在其中一个功能(否则存在歧义)
您必须使enable_if
条件取决于模板参数。
这有效:
#include <iostream>
#include <type_traits>
using namespace std;
template <int N>
struct S
{
template <typename T>
typename enable_if<(sizeof(T)>0) && N==1, int>::type
f(T t) { return 1; }
template <typename T>
typename enable_if<(sizeof(T)>0) && N!=1, T>::type
f(T t) { return 0; }
};
int main()
{
S<1> s1;
S<2> s2;
cout << s1.f(99) << " " << s2.f(99) << endl;
}
答案 3 :(得分:0)
std::enable_if
只是选择函数重载的工具。它是作为来自boost的纯库解决方案实现的。我认为选择正确的重载的规则并不容易。但是在涉及enable_if
的某些情况下要求更改这一点会使其更复杂。因此,您最好使用部分特化和分离enable_if
。