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) 
    ^~~~~~~~ 

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