c++ - 为一组类型专门化功能模板
问题描述
是否可以为不同的类型集创建具有不同行为的函数模板?
假设一个带有模板参数的函数,它应该接受任何类型,没有编译失败
template<typename T>
void foo(T arg){
std::cout << arg;
}
当然,对于没有operator<<
. 我只想写std::cout
幼稚的类型(即数字,,,std:string
)const char *
,对于其他类型,没有任何东西可以打印出来。所以,我尝试了这个(为简化起见,我省略了对std:string
,的检查const char *
)
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
void foo(T arg){
std::cout << arg;
}
template<typename T, typename = typename std::enable_if<!std::is_arithmetic<T>::value, T>::type>
void foo(T arg){
}
也就是说,必须生成没有潜在歧义的重载函数。当然,代码不会编译,因为模板的参数不是模板签名的一部分(因此有两个具有相同签名的模板)。那么有什么办法可以玩吗?
我看到了将后一个函数作为主模板的解决方案,并为声明的类型创建模板专业化,但我不想用相同的定义来膨胀我的代码(并且可能有更多类型的打印)。有什么方法可以使用std::enable_if
或 smth 专门化功能模板吗?
PS Boost 是无关紧要的 PPS 我已经看到了这个答案Specialize Many Templates for a Set of Types,但我不知道如何采用它,即所有可能的类型都可以传递给函数,而不仅仅是几个预定义的
解决方案
您可以直接使用 SFINAE 所需的表达式std::cout << arg
。例子:
template<typename T>
auto foo_imp(T&& arg, int) -> decltype(std::cout << std::forward<T>(arg), throw) /* -> is void */ {
std::cout << std::forward<T>(arg);
}
template<typename T>
void foo_imp(T&&, long) {
// Do nothing.
}
template<typename T>
void foo(T&& arg) {
foo_imp(std::forward<T>(arg), 0); // int is the best match for 0.
}
struct X {};
int main() {
foo(1); // calls foo_imp(int&&, int)
foo(X{}); // calls foo_imp(X&&, long)
}
在上面std::forward
用于迂腐地保留 的值类别arg
。
推荐阅读
- javascript - 登录 PHP:使用 MYSQL 在单页中进行用户级别登录
- thymeleaf - Compare values in DropDown list and select Default value in Thymeleaf
- powershell - 如何使用 PowerShell 从 SharePoint 获取所有文档的列表?
- javascript - React-Redux - Parsing error: Unexpected token, expected "," in action creator
- python - 从 VBA(或命令行)启动 Anaconda Prompt
- amazon-web-services - AWS SDK doesn't work on Azure Web App service
- php - MySQL not updating all records from loop
- amazon-web-services - Amazon S3 将多个文件从一个存储桶复制到另一个存储桶
- java - 如何使用递归回溯器java制作迷宫
- c# - Comparing two files and displaying which line is different