如果类仅通过要求启用单个成员函数,仍然可以模棱两可地超载

If a class has only a single member function enabled via requires can it still be ambiguously overloaded?

本文关键字:超载 模棱两可 函数 成员 单个 启用 如果      更新时间:2023-10-16

例如,此代码有效吗?

template <class T>
struct A {
  void f() 
    requires std::is_same_v<T, int>
  {
  }
  void f(int) 
    requires !std::is_same_v<T, int>
  {
  }
};
int main() {
  auto fptr = &A<int>::f;
  return 0;
}

它不会与GCC编译,但似乎应该对我有用。

如果类仅通过requires启用了单个成员函数,它仍然认为它已超载吗?

是。

[C++ Concepts TS: 13/1]:当在同一范围中为单个名称指定两个或更多不同的声明时,据说该名称被超载。通过扩展,在同一范围内声明相同名称但具有不同类型或不同相关约束的两个声明(14.10.2(被称为Overload offload anderad声明。只有函数和功能模板声明才能超载;变量和类型声明不能超载。

超载分辨率在它们之间选择:

[C++ Concepts TS: 13.3.2/1]:来自为给定上下文构建的候选函数集(13.3.1(,选择一组可行的函数,从中可以通过比较最佳拟合的参数转换序列和关联的约束来从中选择最佳函数(从中选择最佳函数(13.3.3(。可行函数的选择考虑了关联的约束,如果任何(14.10.2(,以及参数和函数参数之间的关系以外的其他转换序列等级。


例如,此代码有效吗?

是!

尽管这里有两个过载,但在获取f的地址时,一个没有限制的不满意的考虑是:

[C++ Concepts TS: 13.4/4]: 从一组选定的功能中取出所有不满意的约束的功能 [..]

因此,这似乎是一个编译器错误。

引用的版本:N4377,日期为2015-02-09

如果尝试从问题行中删除自动类型扣除,则编译器给出了更合适的消息:

prog.cc: In function 'int main()':
prog.cc:18:40: error: conversion from '<unresolved overloaded function 
 type>' to non-scalar type 'std::function<void()>' requested
   std::function<void()> fptr = A<int>::f;

试图解决A::f有两个可能的选项,编译器如何知道您没有搞砸并打算致电另一个。