Qualification adjustment (const / volatile) may cause ambiguity

Can someone help me understand why the code below does not compile (VS2010) when getters are const?

Here's the test code:

#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; } 

I know that boost :: system :: error_code is converted to bool, but cannot understand why const causes ambiguity. Here is the error message from 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 
+4
source share
2 answers

In order to resolve overloads, the list of parameters for two overloads is class socket &, bool and const class socket &, boost::system::error_code & .

Callers: class socket &, boost::system::error_code &

To match the first overload, the following conversion is necessary:

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

In C ++ 0x 13.3.3p1:

Define ICSi (F) as follows:

- if F is a static member function, ICS1 (F) is determined so that ICS1 (F) is neither better nor worse than ICS1 (G) for any function G, and, symmetrically, ICS1 (G) is neither better nor worse ICS1 (F); otherwise,

- let ICSi (F) denote the implicit sequence of transformations that converts the i-th argument in the list, the viable function F is of the type of the i-th parameter. 13.3.3.1 defines implicit conversion sequences and 13.3.3.2 determines what it means that one implicit a conversion sequence is a better conversion sequence or a worse conversion sequence than another.

Given these definitions, a viable function F1 is defined as better than another viable function F2, if for all arguments i, ICSi (F1) is no worse than the transformation scheme than ICSi (F2) , and then

....

This shows that none of the coincidences of the two overloads meets this requirement. For one function, one transformation sequence is better and one transformation worse than the corresponding transformation sequence of another function, so a viable function cannot be defined.

If the second overload is not const , then for the second overload the conversion sequence does not need any conversion (both are identical), therefore it is better than the other overload, therefore it is not ambiguous.

+1
source

Two conversions with the same rank are possible:

  • socket &socket const &

  • boost::system::error_codebool

You can resolve the ambiguity manually:

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

Source: https://habr.com/ru/post/1385527/


All Articles