那么增强模板enable_if呢?
what about enhance template enable_if
首先我使用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的通用函数。
您可以通过以下方式解决这个问题:
- 在函数模板中设置互斥的sfinae约束;
- 强制
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;}
};
下面是一个的实例
首先,我怀疑您的代码中有一个错字。启用应该在T上参数化的if,编译:typename enable_if<N==1,T>::type
而不是typename enable_if<N==1,int>::type
只使用第二个重载,同时启用if,并带反转条件。工作原理:
#include <iostream>
using namespace std;
template<int N>
struct S{
template<class T>
typename enable_if<N==1,T>::type
f(T t) {return 1;};
template<class T>
typename enable_if<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;
return 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;
}
生活例子
std::enable_if
只是一个选择函数重载的工具。它是作为来自boost的纯库解决方案实现的。我认为选择正确的重载的规则并不容易。但是要求在涉及enable_if
的某些情况下改变这一点会使它变得更加复杂。所以你最好使用部分专门化和析取enable_if
。
相关文章:
- 我的简单if-else语句是如何无法访问的代码
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何删除peer if else分支中的冗长句子
- 我似乎对if/else的基本语句有问题:/
- if数组上的随机数
- 将按位if条件转换为普通if条件
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 使用if-else将数字转换为单词
- 为什么简单的算术减法在"if"条件下不起作用?
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- SFINAE with boost enable if