1

I tried to compile someone's intrusive_ptr with clang 3.7 & -std=c++1z, and it generates errors below ( GCC 5.2.1 is Ok ) :

In file included from test_intrusive_ptr.cpp:10:
./intrusive_ptr.hpp:539:53: error: '_Weak_observer' is a private member of
'std::_Intrusive_ptr_impl::_Deleteable<std::default_delete<foo> >'
    using _Observer = typename intrusive_base<_T, _D>::_Weak_observer;
                                                       ^
test_intrusive_ptr.cpp:27:21: note: in instantiation of template      class 'std::intrusive_weak_ptr<foo>' requested here
template class std::intrusive_weak_ptr<foo>;
                ^
./intrusive_ptr.hpp:141:9: note: implicitly declared private here
class _Weak_observer : public _Ref_count_base {
                  ^
./intrusive_ptr.hpp:556:24: error: '__create_observer' is a private member of
'std::_Intrusive_ptr_impl::_Deleteable<std::default_delete<foo> >'
    __observer = __rhs->__create_observer();
                                        ^
test_intrusive_ptr.cpp:27:21: note: in instantiation of member function 'std::intrusive_weak_ptr<foo,
std::default_delete<foo> >::intrusive_weak_ptr' requested here
    template class std::intrusive_weak_ptr<foo>;
                ^
./intrusive_ptr.hpp:174:20: note: implicitly declared private here
_Weak_observer * __create_observer() const volatile {
                             ^
2 errors generated.

But the code compiles well after I add public at line 134. Is that a bug in Clang?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Cu2S
  • 667
  • 1
  • 5
  • 21
  • NB. This code causes undefined behaviour by attempting to add to `namespace std` – M.M Dec 03 '15 at 05:35
  • BTW the problem seems to be with `_Weak_observer` being private, not the friend declarations – M.M Dec 03 '15 at 05:36
  • @M.M You missed content in [test_intrusive_ptr.cpp](https://github.com/lhmouse/intrusive_ptr/blob/master/test_intrusive_ptr.cpp) ,so the templates aren't instantiated and of course compile well. Add missed content like [this](http://goo.gl/LnPBz2). By the way, this is a proposal for adding intrusive_ptr to StdLib. – Cu2S Dec 03 '15 at 05:58
  • 1
    [Minimized example](http://coliru.stacked-crooked.com/a/96e22d9d5b636594) next time, please. This takes less than 20 lines to reproduce, not 700+. I'm too tired to parse the name lookup rules in the standard right now, but the simplest fix/workaround is to qualify the name in the friend declaration - `template<...> friend class std::intrusive_weak_ptr;`. – T.C. Dec 03 '15 at 10:54
  • @T.C. IIRC there was some name lookup rule about finding friends only in the nearest enclosing namespace. See http://stackoverflow.com/a/31008701/ – dyp Dec 03 '15 at 11:09
  • 3
    This is probably one of [gcc's bugs with access in template contexts](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59002). The friend-declaration in @T.C. 's example may not find the declaration at global scope because of [C++ namespace.memdef p3](http://eel.is/c++draft/namespace.memdef#3) – dyp Dec 03 '15 at 11:20

0 Answers0