受C ++ 20约束影响的gcc干线函数重载解析行为的说明

问题描述

我了解到C ++ 20的约束偏序解决了旧的问题,即为特定结构及其任何派生结构重载泛型​​函数,并对其进行了测试。即,以下代码:

#include <concepts>

struct A {};
struct B : A {};

template <typename T>
void f(T&) {}
template <typename T> requires std::derived_from<T,A>
void f(T&) {}

int main() {
    B b;
    f(b);
    return 0;
}

正如在使用x86-64 gcc 10.2的godbolt.org上测试的那样,调用f(b)成功调用了第二个实现,而旧的编写方法void f(A&) {}无法与通用重载竞争。 (我知道,在C ++的较早标准中,这两种功能上也都有选择标记或SFINAE之类的方法才能正确执行此操作。)

但是,如果我将函数定义更改为以下内容:

template <typename T>
void f(T) {}
template <typename T> requires std::derived_from<T,A>
void f(T&) {}

(其中一个签名是带有参考的,另一个签名没有;如果两个都被切换,则同样如此),则该技巧停止工作,并且gcc报告呼叫f(b)含糊不清。我想知道这是否是C ++ 20标准中指定的行为(以及如何解释),以及是否确实打算实现此类重载(也许泛型重载针对特定类的对象按值复制所有内容)我希望使用引用对对象执行完全相同的操作-我知道这是一种罕见的情况,但以防万一这是必需的。 SFINAE的旧方法?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

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