https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64596
Bug ID: 64596 Summary: Friendship not recognized and template param deduction error Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: petschy at gmail dot com Explanation of the attached code: Str is a stream class, Txn is its helper, thus needs access to Str's private members. There is also a Glue class that is supposed to glue together a stream implementation and the streamed type. This way the streamed type needs to grant friend access only to Glue, and need not / should not know about the streams. The stream might also grant friendship to Glue. For a specific stream type and streamed type Glue should be specialized and perform the actual streaming there, optionally using the private members of the stream and the streamed type. Implementing this I ran into two errors and though I have a workaround, it's not clear to me that the errors are due to some strange interaction of the language rules, or bugs in the compiler. Plan A: the Txn class is separate from Str. Str wants to grant friendship to Txn, but with the same E type only. template<bool R> friend class Txn<E,R>; won't work as the compiler sees this as a specialization. To work around this I used a templated using directive: template<bool R> using Tx = Txn<E,R>; and granted friendship to Tx. Unfortunately this doesn't work, when Txn tries to access the private member i, an error is reported. Plan B: move Txn inside StrB. This solves the access problem, but then there's a new error: the Glue specialization won't compile, telling me that the template params cannot be deduced. This is strange, as the syntax is the same as in Plan A. Plan C: move Txn inside StrC, but create TxnC, a simple forwarder class outside, too. This way the access works, since Txn is inside, and the Glue specialization works since we glue the outside class, TxnC. However, this is tedious with real code. Tested with 4.9.1 and 5.0 (20141222), both give the same errors: g++ -std=c++11 -Wall 20150114-friend.cpp 20150114-friend.cpp:81:8: error: template parameters not deducible in partial specialization: struct Glue<StrBTxn<E, R>, int> // error: template parameters not deducible in partial specialization ^ 20150114-friend.cpp:81:8: note: ‘E’ 20150114-friend.cpp: In instantiation of ‘Txn<E, R>::Txn(Txn<E, R>::S&) [with E = int; bool R = false; Txn<E, R>::S = Str<int>]’: 20150114-friend.cpp:45:38: required from ‘static void Glue<Txn<E, R>, int>::Foo() [with E = int; bool R = false]’ 20150114-friend.cpp:52:30: required from here 20150114-friend.cpp:17:6: error: ‘int Str<int>::i’ is private int i; ^ 20150114-friend.cpp:28:3: error: within this context ++s.i; // error: ‘int Str<int>::i’ is private ^