【问题标题】:C++ ambiguous overload and constructor with defaultsC++ 模棱两可的重载和带默认值的构造函数
【发布时间】:2017-10-29 22:45:00
【问题描述】:

我有一个程序的代码可以完美运行,但编译器仍然会输出这个烦人的警告:

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:

我的程序的简化版本是:

#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() 重载有什么问题。 有什么想法吗?

【问题讨论】:

    标签: c++ operator-overloading default-value overloading


    【解决方案1】:

    嗯,

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

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

    我希望有一天它可以帮助某人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多