2

I could not understand the second foo call in the code below. How does it call global foo function. Why does (foo) call struct A's int()? Can you help me?

#include <stdio.h>
#include <utility>
#include <iostream>
using namespace std;

namespace MySpace{
    struct A{
        operator int () const {
            cout <<"operator" << endl;
           return 1;        
        }
    };
    
    void foo(A){
        std::cout<< "1" << endl;
    }
}

void foo(int){
    std::cout << "--2" << endl;
}


int main()
{
    
    MySpace::A x;
    foo(x);
    (foo)(x);
   
    return 0;
}

I could not understand the second foo call. How does it call global foo function. Why does (foo) call struct A's int()? Can you help me?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Veriginia
  • 31
  • 2

1 Answers1

3

The 1st one works because ADL finds MySpace::foo and it wins in overload resolution against ::foo and gets called.

For the 2nd one, adding parentheses like (foo) prevents ADL; then MySpace::foo can't be found, only ::foo is found and gets called. A is converted to int implicitly (by A's conversion operator) for it to be called.

BTW: You can mark the conversion operator as explicit to forbid the implicit conversion from A to int. Then the 2nd one would fail. E.g.

namespace MySpace {
    struct A{
         explicit operator int () const {
            cout <<"operator" << endl;
           return 1;        
        }
    };
    
    void foo(A){
        std::cout<< "1" << endl;
    }
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405