C++ 成员函数不明确

标签 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.在void Foo(const AClass<T> &other)的末尾添加一个const也是

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

或者其他一些方式。

这3个以上整改是怎么回事,原来的问题是什么?

最佳答案

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

AClass(T a) {}

给定a1.Foo(1) :

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

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

您的前两个修复使这两个函数在不带隐式对象参数的情况下同样好用,因此 T版本明确获胜。您的第三次修复使得 AClass<T>函数不再可行,因为隐式转换不再存在。

关于C++ 成员函数不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40814691/

相关文章:

c++ - 通告包括依赖/转发声明

c++ - 类型、整型常量和模板模板参数的可变参数模板

c++ - 在完美图中寻找最大团

c++ - 继续执行另一个线程

c++ - 基于范围的 for 循环可以接受类型参数吗?

c++11 - std::atomic 作为 std::map 的值

c++ - 有没有办法使用纯 gdb 脚本来测试我们是否在断点上?

c++ - 模板化(或以某种方式自动)方法的返回值

c++ - 这些创建对象的方法有什么区别?

c++ - numeric_limits<int>::is_modulo 在逻辑上是否矛盾?