C ++成员函数含糊不清

时间:2016-11-26 03:44:17

标签: c++ c++11

我已经看到已经存在关于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{
  2. 的const

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

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

    或其他一些方式。

    这三个或更多的整改如何破坏,原始问题是什么?

1 个答案:

答案 0 :(得分:1)

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

AClass(T a) {}

鉴于a1.Foo(1)

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

因为这两个函数都没有明显优于另一个函数(每个函数在一个参数上更好而在另一个参数上更差),所以调用是不明确的。

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