
Jean-Francois Bastien wrote:
Niels,
Correct me if I'm wrong :)
Well... I do appreciate your pedanticism, but I think you're wrong. All the compilers I tried accept the function calls to the inline friend function, operator-(safe_int,safe_int), including MSVC 2008 SP1, Comeau (www.comeaucomputing.com/tryitout), and g++ 4.1.2, run at http://codepad.org/dB9IbQJ7
You might want to have a look at [temp.inject] ("Friend names declared within a class template"). Quoting the latest C++0x Working Draft, www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2857.pdf, 14.7.5/2 (slightly reformatted):
"As with non-template classes, the names of namespace-scope friend functions of a class template specialization are not visible during an ordinary lookup unless explicitly declared at namespace scope (11.4). Such names may be found under the rules for associated classes (3.4.2). [ Example:
template<typename T> struct number { number(int); friend number gcd(number x, number y) { return 0; }; };
void g() { number<double> a(3), b(4); a = gcd(a,b); // finds gcd because number<double> is an // associated class, making gcd visible // in its namespace (global scope) b = gcd(3,4); // ill-formed; gcd is not visible } -end example ]
I might very well be wrong, that part of the standard has always been a bit shady to me and had a ring of "pre-standard stuff". That being said compilers aren't the best way to verify standard compliance ;)
I believe that the friend becomes visible once the template is instantiated for a specific type. Therefore there is a gcd for number<double> visible in the example above, but not for any other types. Bo Persson