CPO名称耦合弊端、语义校验缺陷及替代方案技术问询
自定义点对象(CPO)与名称耦合是否属于设计弊端?
CPO(自定义点对象)可以通过concept检查用户自定义重载函数的签名要求(比如输入类型、输出类型等),但完全无法校验函数的语义逻辑,这确实是个问题。比如下面这段代码:
namespace My_A{ struct A{}; void some_name(A);//不符合concept要求 } namespace My_B{ struct B{}; int some_name(B);//符合concept,但执行无关逻辑 } template<typename T> concept usable_some_name = requires(T arg) { some_name(arg) -> int; }; struct __use_fn{ template<typename T> int operator()(T a) { if constexpr (usable_some_name<T>) return some_name(a); // ... } }; __use_fn use{};
这段代码能筛选掉签名不符合的函数,但无法保证“通过校验”的函数会执行预期的操作。要避免出错,要么得规避所有CPO可能用到的名称(显然不现实),要么得确保自己的同名函数(如果存在)完全符合CPO预期的语义(这无疑是不合理的负担)——毕竟所有CPO都有可能触发调用。
仅仅因为函数名称和范围算法所用名称相同,就必须让函数行为符合范围算法的预期,这算不算不合理要求?
对比传统的定制方式:
template <> struct hash<my_type> { // ... }
或者:
priority_queue<my_type, vector<my_type>, my_type_greater> pq;
这些传统方式都是显式指定定制代码才会被调用,完全不存在CPO那样的误匹配风险。
虽然我理解CPO的设计目的和优势,但它是否带来了过度耦合?有没有更优的方案(比如tag_invoke,我对它不太了解)能解决这个问题?
内容的提问来源于stack exchange,提问作者zclll
相关产品推荐
相关产品推荐

