c++ - 如何为特定类型专门化模板类方法?
问题描述
我有这样的代码:
class Bar {
public:
void print() {
std::cout << "bar\n";
}
};
template<typename T>
class Foo {
public:
template <typename std::enable_if<std::is_base_of<T,Bar>::value,T>::type>
void print() {
t.print();
}
template <typename>
void print() {
std::cout << t << std::endl;
}
private:
T t;
};
int main() {
// Foo<int> foo1;
Foo<Bar> foo2;
foo2.print();
}
这段代码的目的是:如果T t
是 的一个Bar
或一个子类Bar
,则foo.print()
推断为void print() {t.print();}
,否则推断为void print() {std::cout << t << std::endl;}
,但事情并没有像我预期的那样工作。编译器错误:
"一个非类型模板参数不能有类型'typename std::enable_if::value, Bar>::type' (aka 'Bar')",
这段代码有什么问题?
解决方案
您应该
print()
对函数模板进行重载(以使SFINAE工作),否则始终首选非模板函数。您应该让其
print()
采用自己的模板类型参数;不应该T
直接对类模板参数进行类型检查,函数模板重载解析和 SFINAE 是对函数模板本身进行的,类模板不参与。您可以将部分移动
std::enable_if
到返回类型。如果您希望类型为或 的派生类,则应将指定的顺序更改为
std::is_base_of
(即std::is_base_of<Bar, X>
不是) 。std::is_base_of<X, Bar>
Bar
Bar
例如
template <typename X = T>
typename std::enable_if<std::is_base_of<Bar, X>::value>::type print() {
t.print();
}
template <typename X = T>
typename std::enable_if<!std::is_base_of<Bar, X>::value>::type print() {
std::cout << t << std::endl;
}
推荐阅读
- kotlin - 为什么 check()、require() 和 assert() 不会产生智能转换?
- java - 为什么当我从 kotlin 项目程序中调用 java 类时总是停止工作
- c++ - 无法在 CLion 中构建 c++ 项目
- powershell - 如何在PowerShelll中列出匹配目录的内容,无论Get-ChildItem字符串输入是否包含通配符
- r - 如果失败则重新执行函数(R)
- sql - SQL Server - 如何聚合和保留“顶部”值
- java - 所有 CRUD 操作的线程安全列表
- keras - 在不使用嵌入的情况下在 keras 中屏蔽 LSTM 中的零输入
- django - vue.js webpack 和静态图像(没有 vuecli 和 nodejs 开发服务器)
- excel - excel VBA - 修改表格