如何重载概念的功能? [英] How can I overload a function for a concept?

查看:69
本文介绍了如何重载概念的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个功能模板和各种专门化的重载。模板。由于在重载解析期间重载比模板版本更好,因此它们将始终被优先处理。

Suppose I have a function template and various overloads that "specialize" the template. As overloads are a better match than the template version during overload resolution, they will always get priorized.

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";

现在,我的情况是我的专业化知识可以适用于整套(不相关的)类型,但是满足一个概念的约束,例如:

Now I have the case where I have a specialization that could work for a whole set of (unrelated) types, that however satisfy constraints from a concept, e.g.:

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)不明确。当然,我可以通过为所有类型(我目前知道)提供显式重载来解决此问题,但是由于实际应用程序中类型的数量很大(客户端可能会添加更多这种类型的概念),并且这些类型中的每一个类型都将非常相似(直到编译时才知道很小的差异),这将是很多重复。

Unfortunately, this overload is on par with the generic case, so a call like dispatch(1.0f) is ambiguous. Of course, I could solve this by providing explicit overloads for all types (that I currently know), but as the number of types in my real application is large (and more types of this concept may be added by clients) and the code for each of these types would be very similar (up to small differences that are known at compile-time), this would be a lot of repetition.

是否有一种方法可以为整个概念?

Is there a way to overload a function for a whole concept?

推荐答案

约束函数模板只有在具有相同的模板参数列表。因此,要么使通用变量取一个值(以便都取一个 T ):

A constrained function template only beats an unconstrained function template when they have the same template-parameter-lists. So either make the generic one take a value (so that both take a T):

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

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

Or make the floating point one take a forwarding reference (so that both take a 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";
}

这篇关于如何重载概念的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆