【问题标题】:How can I overload a function for a concept?如何为概念重载函数?
【发布时间】:2020-12-02 10:07:58
【问题描述】:

假设我有一个函数模板和各种“专门化”模板的重载。由于在重载解析期间重载比模板版本更匹配,因此它们将始终获得优先级。

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

有没有办法为整个概念重载函数?

【问题讨论】:

    标签: c++ overloading c++20 overload-resolution c++-concepts


    【解决方案1】:

    只有在有the same template-parameter-lists and function parameter types 时,受约束的函数模板才能胜过不受约束的函数模板。所以要么让通用的取一个值(这样两者都取一个T):

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

    或者让浮点数取一个转发引用(这样两者都取一个T&amp;&amp;):

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

    【讨论】:

    • 这当然是一个不错的陷阱。
    • 他们已经有了相同的模板参数列表;是(函数)参数类型不匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多