C 成员函数是模棱两可的



我已经看到C 中的歧义错误已经存在问题,但这是某种不同的问题。

假设我们的代码如下:

#include <iostream>
#define LDBG(msg) 
  std::cout << "[" << __FUNCTION__ << " " << __LINE__ << "] " << msg << std::endl;
template<typename T>
struct AClass{
  AClass(T a) {}
  void Foo(const AClass<T> &other){
    LDBG("")
  }
  void Foo(const T &key) const{
    LDBG("")
  }
};
int main(){
  AClass<int> a1{1};
  AClass<int> a2{2};
  a1.Foo(1);
  a1.Foo(a2);
  LDBG("")
  return 0;
}

这将产生汇编错误,例如:

error: call to member function 'Foo' is ambiguous
    a1.Foo(1);
    ~~~^~~
note: candidate function
    void Foo(const AClass<T> &other){
         ^
note: candidate function
    void Foo(const T &key) const{
         ^
1 error generated.

如果以下情况,错误将消失:

  1. 在第14行(void Foo(const T &key) const{)处删除const

或2。在void Foo(const AClass<T> &other)的末尾加一个const

或3。将构造函数更改为AClass() {}(也是主函数中A1和A2的相对初始化)

或其他一些方法。

这三个或多个纠正如何,原始的问题是什么?

此构造函数定义了从 TAClass<T>的隐式转换:

AClass(T a) {}

给定a1.Foo(1)

  • void Foo(const AClass<T> &other)是隐式对象参数的更好匹配,并且在other上匹配更差(因为它需要用户定义的转换)
  • void Foo(const T& key) constkey上更好的匹配(因为它是确切的匹配),并且由于添加了const

因为这两个功能都不比另一个功能好(每个函数在一个参数上更好,而另一个参数都更好),所以呼叫是模棱两可的。

您的前两个修复程序使这两个函数同样好,w/r/t是隐式对象参数,因此T版本明确获胜。您的第三个修复程序使AClass<T>功能不再可行,因为隐式转换不再存在。

最新更新