C++17中如何让hom<A,B>与hom<(A,B),C>分别别名std::function?
实现贴近数学符号的
hom函数类型别名(C++17) 核心需求梳理
- 单变量场景:
hom<X, Y>等价于std::function<Y(X)> - 双变量场景:期望用贴近数学符号的方式表达
(A,B)到C的函数集,替代std::function<C(A,B)>
可行实现方案
方案一:用std::pair模拟有序对定义域
C++模板参数不支持(A,B)这种写法(逗号会被解析为参数分隔符),我们可以用std::pair<A,B>包装双变量定义域,通过模板特化实现接近数学符号的表达:
#include <functional> #include <utility> // 主模板:处理单变量场景 template<typename Domain, typename Codomain> struct HomImpl { using type = std::function<Codomain(Domain)>; }; // 特化模板:处理双变量场景 template<typename A, typename B, typename Codomain> struct HomImpl<std::pair<A, B>, Codomain> { using type = std::function<Codomain(A, B)>; }; // 对外暴露的模板别名 template<typename Domain, typename Codomain> using hom = typename HomImpl<Domain, Codomain>::type;
使用示例
// 单变量:int → std::string hom<int, std::string> str_convert = [](int val) { return std::to_string(val); }; // 双变量:(int, double) → bool hom<std::pair<int, double>, bool> compare = [](int a, double b) { return a > b; };
方案二:直接支持三参数简洁写法
如果觉得std::pair不够直观,也可以直接扩展模板支持三参数形式,完全规避推导问题:
#include <functional> // 单变量版本 template<typename Domain, typename Codomain> using hom = std::function<Codomain(Domain)>; // 双变量版本(C++17允许模板别名重载) template<typename A, typename B, typename Codomain> using hom = std::function<Codomain(A, B)>;
使用示例
hom<int, std::string> str_convert = [](int val) { return std::to_string(val); }; hom<int, double, bool> compare = [](int a, double b) { return a > b; };
关键说明
- C++语法不允许
hom<(A,B),C>这种写法,因为模板参数列表中的逗号会被视为参数分隔符而非有序对的一部分; - 两种方案均完全支持C++17标准,且仅覆盖单、双变量场景,符合需求。
内容的提问来源于stack exchange,提问作者Timtro
相关产品推荐
相关产品推荐

