c++ - 如何使 SFINAE 与模板专业化一起工作?
问题描述
我有一个模板方法foo
。我想有几个不同的实现: for T
,where是内置类型或一些复杂的类vector<T>
。我想使用 SFINAE 来分离内置类型和类的实现,并限制一组允许的类型。vector<vector<T>>
T
以下代码正常工作,但我收到警告消息:
8:37: warning: inline function 'constexpr bool isType() [with T =
std::vector<int>]' used but never defined
8:37: warning: inline function 'constexpr bool isType() [with T =
std::vector<std::vector<int> >]' used but never defined
#include <type_traits>
#include <vector>
using namespace std;
class ComplexClass{};
template<typename T> constexpr bool isType();
template<> constexpr bool isType<int>() {return true;}
template<> constexpr bool isType<ComplexClass>() {return false;}
template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(T& value) {}
template <typename T>
inline typename enable_if<!isType<T>(), void>::type
foo(T& value) {}
template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(vector<T>& value) {}
template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(vector<vector<T>>& value) {}
int main()
{
int a;
vector<int> b;
vector<vector<int>> c;
ComplexClass d;
char e;
foo(a);
foo(b);
foo(c);
foo(d);
// foo(e); // has to lead to an error
return 0;
}
看起来编译器试图传递vector<...>
给第一个enable_if
方法并失败了。但是跳过这些方法会很棒,因为我们有更好的 和 候选vector<T>
者vector<vector<T>>
。有可能吗?
解决方案
看起来您希望将向量重载函数模板限制为仅接受内置类型的向量。否则这些重载不需要 SFINAE。
您还可以使用std::is_fundamental
来检测内置类型:
工作示例:
using namespace std;
class ComplexClass {};
template <typename T>
typename enable_if<is_fundamental<T>::value>::type
foo(T& value) { cout << __PRETTY_FUNCTION__ << '\n'; }
template <typename T>
typename enable_if<!is_fundamental<T>::value>::type
foo(T& value) { cout << __PRETTY_FUNCTION__ << '\n'; }
template <typename T>
typename enable_if<is_fundamental<T>::value>::type
foo(vector<T>& value) { cout << __PRETTY_FUNCTION__ << '\n'; }
template <typename T>
typename enable_if<is_fundamental<T>::value>::type
foo(vector<vector<T>>& value) { cout << __PRETTY_FUNCTION__ << '\n'; }
int main() {
int a;
vector<int> b;
vector<vector<int>> c;
ComplexClass d;
char e;
foo(a);
foo(b);
foo(c);
foo(d);
foo(e);
}
输出:
typename std::enable_if<std::is_fundamental<_Tp>::value>::type foo(T&) [with T = int; typename std::enable_if<std::is_fundamental<_Tp>::value>::type = void]
typename std::enable_if<std::is_fundamental<_Tp>::value>::type foo(std::vector<_Tp>&) [with T = int; typename std::enable_if<std::is_fundamental<_Tp>::value>::type = void]
typename std::enable_if<std::is_fundamental<_Tp>::value>::type foo(std::vector<std::vector<_Tp> >&) [with T = int; typename std::enable_if<std::is_fundamental<_Tp>::value>::type = void]
typename std::enable_if<(! std::is_fundamental<_Tp>::value)>::type foo(T&) [with T = ComplexClass; typename std::enable_if<(! std::is_fundamental<_Tp>::value)>::type = void]
typename std::enable_if<std::is_fundamental<_Tp>::value>::type foo(T&) [with T = char; typename std::enable_if<std::is_fundamental<_Tp>::value>::type = void]
推荐阅读
- python - 如何在 github 上更新 Azure Databricks 笔记本
- ajax - 服务器对 ajax 调用的响应为 200,但在浏览器上我在 Safari 上收到错误 400
- c# - RSACryptoServiceProvider 使用的默认填充是什么?
- mysql - SELF JOIN中SQL查询的AS语句改变结果
- python - 尝试从文件夹中提取随机“.tif”图像并打印图像
- javascript - 为什么 NumberFormat 只能识别四个数字?
- string - 为什么这段代码没有输出。我试图获得反向输出
- java - 练习循环和数组
- ruby - 无法使用 Watir 和 Xpath 点击 href 链接
- swift - 如何将 API 请求中的图像 URL 保存到我的核心数据?