资格调整(常数/不稳定)可能导致歧义

时间:2011-12-09 12:36:52

标签: c++

当getter是const时,有没有人可以帮助我理解为什么以下代码无法编译(VS2010)?

这是测试代码:

#include <boost/system/error_code.hpp>

class socket {
public:

    // setter - throw exception version
void non_blocking(bool mode)
    {
        // ...
    }

    // getter - error code version      
    bool non_blocking(boost::system::error_code& ec) const
    {
        // ...
    }

    // setter - error code version
void non_blocking(bool mode, boost::system::error_code& ec)
    {
        // ...
    }

    // getter - throw exception version    
    bool non_blocking() const
    {
        // ...
    }
};

int main()
{
    socket s;
    boost::system::error_code ec;
    bool result = s.non_blocking(ec);

    return 0;
}

我知道boost :: system :: error_code可以转换为bool,但无法理解为什么const导致歧义。这是来自VS2010的错误消息:

1>c:\projects\pcap++\trunk\main.cpp(145): error C2666: 'socket::non_blocking' : 2 overloads have similar conversions
1>          c:\projects\pcap++\trunk\main.cpp(134): could be 'bool socket::non_blocking(boost::system::error_code &) const'
1>          c:\projects\pcap++\trunk\main.cpp(129): or       'void socket::non_blocking(bool)'
1>          while trying to match the argument list '(boost::system::error_code)'
1>          note: qualification adjustment (const/volatile) may be causing the ambiguity

2 个答案:

答案 0 :(得分:4)

两种同等排名的转化是可能的:

  • socket &socket const &

  • boost::system::error_codebool

您可以手动消除歧义:

bool result = static_cast<socket const &>(s).non_blocking(ec);

s.non_blocking(bool(ec));

答案 1 :(得分:2)

出于重载解析的目的,两个重载的参数列表为class socket &, boolconst class socket &, boost::system::error_code &

调用参数为class socket &, boost::system::error_code &

要匹配第一个重载,需要进行以下转换:

1.
class socket &              -> no conversion
bool                        -> user defined conversion
2.
class socket &              -> qualification conversion
boost::system::error_code & -> no conversion

在C ++ 0x 13.3.3p1中:

  

如下定义ICSi(F):

     

- 如果F是静态成员函数,则定义ICS1(F)   对于任何函数G,ICS1(F)既不比ICS1(G)更好也不差,   并且,对称地,ICS1(G)既不好也不差   ICS1(F);否则,

     

- 让ICSi(F)表示转换的隐式转换序列   列表中的第i个参数为第i个参数的类型   可行函数F. 13.3.3.1定义隐式转换序列   和   13.3.3.2定义了一个隐式转换序列对于更好的转换序列或比转换序列更差的含义   另一个。

     

鉴于这些定义,可行函数F1被定义为a   如果所有参数都,则比另一个可行函数F2更好的功能   i,ICSi(F1)转换序列不比ICSi(F2)差,然后

     

...

由此可以看出,两种重载的匹配都不符合这一要求。对于一个函数,一个转换序列更好,一个转换比另一个函数的相应转换序列更差,因此无法确定可行函数。

如果第二个重载不是const,那么第二个重载的转换序列不需要任何转换(两者都相同),所以这比其他重载更好,因此没有歧义。