0

After reading this answer, I made some tests and I came up with the following code:

#include <iostream>

template <typename T> 
class Test {
    int val{42};

    friend std::ostream & operator << (std::ostream & flux, Test const & instance) {
        return flux << Test<char>{}.val;
    }
};

int main() {
    std::cout << Test<int>{};
    return 0;
}

Using Test<int> in main(), I thought that operator<< couldn't access Test<char>{}.val. But to my surprise, GCC compiled fine.

Then, I tested with Clang and Visual Studio, and both gave me a private member error, as expected (see GCC/Clang demo).

Which compiler is right?

Also, I'm wondering in which case one would need the extrovert version mentioned in the link? Or private access to Test<U> from within operator<< of Test<T> (when T != U)? Do you have any practical examples?

Community
  • 1
  • 1
O'Neil
  • 3,790
  • 4
  • 16
  • 30

1 Answers1

0

I believe Clang/VS are using the correct behavior, because if you create a new instance (as in your example) instead of using the friended instance from the parameters I believe it resets the access to be as if it's from outside.

As for the extra question, I can't think of a practical example the extrovert, but I imagine it's there for the same reason as many things in C++, to let you do it that way if you want to. Maybe use it to convert from one type to another? not sure, sorry^^;

PS sorry for the original confusion.

Matthew Clark
  • 571
  • 1
  • 9
  • 33
  • 1
    _"The DEMO you linked now shows basically the same error as Clang or VS"_ No, look closer! – Lightness Races in Orbit Sep 07 '16 at 01:39
  • "g++ -std=c++11 main.cpp && echo "GCC OK" && clang++ -std=c++11 main.cpp GCC OK main.cpp:8:37: error: 'val' is a private member of 'Test' return flux << Test{}.val; ^ main.cpp:13:15: note: in instantiation of member function 'operator<<' requested here std::cout << Test{}; ^ main.cpp:5:9: note: implicitly declared private here int val{42}; ^ 1 error generated. " That's almost exactly what I got form clang. – Matthew Clark Sep 07 '16 at 02:59
  • 1
    That _is_ the clang output. GCC emits no diagnostics. That's why the `echo "GCC OK"` is there - to show that the first diagnostics come from the call to clang. – Lightness Races in Orbit Sep 07 '16 at 03:05
  • Ah, sorry. Never used that site before and before the link was simply labeled as DEMO. – Matthew Clark Sep 07 '16 at 07:24
  • It wasn't very clear. I interpreted it in just the same way you did, at first. – Lightness Races in Orbit Sep 08 '16 at 02:18