如何重载概念的功能?

问题描述

假设我有一个功能模板和各种“专门化”该模板的重载。在解决重载过程中,与模板版本相比,重载是更好的匹配,因此它们将始终获得优先级。

template <typename T>
void dispatch(T&& t) {
    std::cout << "generic\n";
}

void dispatch(int) {
    std::cout << "int\n";
}

dispatch(5); // will print "int\n"
dispatch(nullptr); // will print "generic\n";

现在我遇到的情况是,我拥有一个可以适用于整套(不相关)类型的专业化知识,但是满足了诸如以下概念的约束条件:

template <std::floating_point T>
void dispatch(T t) {
    if constexpr(std::is_same_v<T,float>) std::cout << "float\n";
    else std::cout << "unknown\n";
}

不幸的是,这种重载与一般情况是一样的,因此像dispatch(1.0f)这样的调用是模棱两可的。当然,我可以通过为所有类型(我目前知道的)提供显式重载来解决此问题,但是由于实际应用程序中类型的数量很大(客户端可能会添加更多这种类型的概念),并且这些类型中的每一个类型都将非常相似(直到编译时已知的微小差异为止),这将是很多重复。

是否有办法为整个概念重载功能?

解决方法

受约束的功能模板只有在具有the same template-parameter-lists时才能击败不受约束的功能模板。因此,要么使通用值取一个值(使两者都取T):

template <typename T>
void dispatch(T t) {
    std::cout << "generic\n";
}

或者使浮点数成为转发参考(以使两者都采用T&&):

template <typename T>
    requires std::floating_point<std::remove_cvref_t<T>>
void dispatch(T&& t) {
    if constexpr(std::is_same_v<T,float>) std::cout << "float\n";
    else std::cout << "unknown\n";
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...