Boost logo

Boost :

From: rwgk_at_[hidden]
Date: 2001-05-22 13:10:46


Is the following piece of code supposed to work with a fully
conforming
compiler?

#include <iostream>

namespace my {

  enum semantics { search_namespace };

  template <class T>
  struct a_friend {
    friend T foo1(semantics, const T& v) { return v * 2; }
  };
}

namespace { // unnamed
  struct X {
    inline X(int v) : m_v(v) {}
    inline int operator*(const int& rhs) const { return m_v * rhs; }
    int m_v;
  };
}

int main() {
  std::cout << X(123) * 3 << std::endl;
  my::a_friend<X> f;
  std::cout << foo1(my::search_namespace, X(123)).m_v << std::endl;
  return 0;
}

Here is what I find:

gcc-2.95.2: works, but only because foo1 is instantiated in the
global namespace. This behavior is usually considered a bug.

Visual C++ 6.0 SP4:
        simple.cpp(24) : error C2065: 'foo1' : undeclared identifier
SGI MIPSpro Compilers: Version 7.3.1.1m (older EDG front-end):
        The identifier "foo1" is undefined.
Compaq C++ V6.2 (version 240 EDG front-end):
        cxx: Error: simple.cpp, line 24: identifier "foo1" is
undefined
For all three compilers:
After fully qualifying my::foo1(...).m_v: works, but only
because foo1 is instantiated in namespace my, the namespace of its
class. foo1 is found by ordinary lookup. This is non-conforming
behavior.

Compaq C++ V6.3 (version 243 EDG front-end):

cxx: Warning: simple.cpp, line 9: external routine uses unnamed
namespace.
          detected during instantiation of class
                    "my::a_friend<T> [with T=<unnamed>::X]" at line 23
    friend T foo1(semantics, const T& v) { return v * 2; }
-------------^
cxx: Error: simple.cpp, line 24: identifier "foo1" is undefined
  std::cout << foo1(my::search_namespace, X(123)).m_v << std::endl;
---------------^

It does not help to fully qualify foo1(...).m_v.
The warning disappears if X is declared in a named namespace, but
foo1 is not found anyway. From that I conclude that foo1 is
instantiated in the namespace of the template argument.
However, foo1 is also not found if fully qualified with the
namespace identifier of the template argument.
Isn't the my::search_namespace argument supposed to enable Koenig
lookup?
Can foo1 be found at all?

Are all the compilers broken one way or another?

Thanks!
        Ralf

P.S.: The questions above are related to a problem with
the Boost.Python library.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk