0

我有一个程序,仅仅完美的作品,但编译器仍然输出这个恼人的警告代码:C++暧昧过载和构造器默认

warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: 

我的程序的simplyfied版本是:

#include <iostream> 
#include <iomanip> 

class point 
{ 
public: 
    point(int x = 0, int y = 0) 

    : _x(x), _y(y) 
    {} 

    point(const point &p) 
    : _x(p._x), _y(p._y) 
    {} 

    int & x() { return _x; } 
    int & y() { return _y; } 

private: 
    int _x, _y; 
}; 

class matrix 
{ 
public: 
    int operator()(int x, int y) const 
    { return _array[ index(x, y) ]; } 

    int operator()(point<int> p)  const 
    { return operator()(p.x(), p.y()); } 

    int operator()(int x, int y, int value) 
    { 
     _array[ index(x, y) ] = value; 
     return _array[ index(x, y) ]; 
    } 

    int operator()(point<int> p, int value) 
    { return operator()(p.x(), p.y(), value); } 

private: 
    int _array[ 4 * 5 ]; 

    int index(int x, int y) const 
    { return y * Width + x; } 
}; 

int main() 
{ 
    std::cout << "Filling matrix." << std::endl; 
    matrix< int, 4, 5 > m; 

    for (int y = 0; y < 5; ++y) 
     for (int x = 0; x < 4; ++x) 
     { 
      m(x, y, (y * 4 + x)); 
     } 

    std::cout << "Reading matrix." << std::endl; 

    for (int y = 0; y < 5; ++y) 
    { 
     std::cout << std::endl << "|"; 

     for (int x = 0; x < 4; ++x) 
     { 
      std::cout << std::setw(3) << std::setfill(' ') << m(x, y) << " |"; 
     } 
    } 

    std::cout << std::endl << "Done." << std::endl; 
} 

我看不到我的operator()过载有什么问题。 任何想法?

回答

0

嗯,

我花了一些时间来弄清楚这个警告的实际原因。由于我的程序运行良好,我只是忽略了直到今天的警告,我认为分享它会很有用,所以世界各地的其他人可以节省一些时间。

经过大量围绕operator()结构,我决定去看看上攻和修修补补的不知道为什么我会被编译混淆了point单个值,并采取第二个参数为value

我发现我已经为我的point构造函数延迟添加了默认值,所以我也可以使用它作为默认构造函数。 当我添加这个默认值时,我没有注意到任何人都可以通过忽略第二个参数来使用这个构造函数,这导致了我的错误。

**不注意的危险! **

只是为了搞笑,我为如下构造我:

#ifdef AMBIGUOUS 
    point(int x = 0, int y = 0) 
#else 
    point() 
    : point(0, 0) {} 

    point(int x, int y) 
#endif 

然后我可以清除它之前尝试我的解决方案:

> g++ ambig_param.cpp -o ambig_param -Wall -std=c++14 

确定。编译没有问题,而后者:

> g++ ambig_param.cpp -o ambig_param -Wall -std=c++14 -DAMBIGUOUS 
ambig_param.cpp: In function ‘int main()’: 
ambig_param.cpp:68:66: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: 
    std::cout << std::setw(3) << std::setfill(' ') << m(x, y) << " |"; 
                   ^
ambig_param.cpp:27:4: note: candidate 1: T matrix<T>::operator()(T, T) const [with T = int] 
    T operator()(T x, T y) const 
    ^~~~~~~~ 
ambig_param.cpp:39:4: note: candidate 2: T matrix<T>::operator()(point<int>, T) [with T = int] 
    T operator()(point<int> p, T value) 
    ^~~~~~~~ 

我希望它可能有助于某人一天。