https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72104

            Bug ID: 72104
           Summary: Inner templated class with stream operator fails to
                    compile
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: romain.geissler at amadeus dot com
  Target Milestone: ---

Hi,

I am having issues with code that used to build fine with gcc 4.9 and 5.3, but
doesn't work anymore with gcc 6.1.1 (20160725). I am not actually sure this is
valid C++ though...

cat test.cpp                                                                   
                                                        11:38PM
#include <iostream>

// The following two lines are required to build with clang.
//template <typename T> class UnrelatedClass;
//template <typename T> std::ostream& operator<<(std::ostream&, const
UnrelatedClass<T>&);

class TopLevelClass
{
    private:
        template <typename T> class InnerClass;
        template <typename T> friend std::ostream& operator<<(std::ostream&,
const TopLevelClass::InnerClass<T>&);

        template <typename T> class InnerClass
        {
            friend std::ostream& operator<< <>(std::ostream&, const
TopLevelClass::InnerClass<T>&);

            int _x;
        };

    public:
        void f(std::ostream& ioStream);
};

template <typename T> std::ostream& operator<<(std::ostream& ioStream, const
TopLevelClass::InnerClass<T>& iInnerClass)
{
    ioStream << iInnerClass._x << std::endl;

    return ioStream;
}

void TopLevelClass::f(std::ostream& ioStream)
{
    InnerClass<int> aInnerClass;

    ioStream << aInnerClass;
}

int main()
{
    TopLevelClass aTopLevelClass;
    aTopLevelClass.f(std::cout);
}



/opt/1A/toolchain/x86_64-2.6.32-v3-3/bin/g++ test.cpp -o test                  
                                                        11:38PM
test.cpp:15:42: error: declaration of ‘operator<<’ as non-function
             friend std::ostream& operator<< <>(std::ostream&, const
TopLevelClass::InnerClass<T>&);
                                          ^~
test.cpp:15:42: error: expected ‘;’ at end of member declaration
test.cpp:15:45: error: expected unqualified-id before ‘<’ token
             friend std::ostream& operator<< <>(std::ostream&, const
TopLevelClass::InnerClass<T>&);
                                             ^
test.cpp: In instantiation of ‘std::ostream& operator<<(std::ostream&, const
TopLevelClass::InnerClass<T>&) [with T = int; std::ostream =
std::basic_ostream<char>]’:
test.cpp:35:17:   required from here
test.cpp:26:29: error: ‘int TopLevelClass::InnerClass<int>::_x’ is private
within this context
     ioStream << iInnerClass._x << std::endl;
                 ~~~~~~~~~~~~^~
test.cpp:17:17: note: declared private here
             int _x;
                 ^~


It was my understanding that friend declarations also counted as regular
declaration. But here gcc doesn't seems to actually like the friend declaration
inside TopLevelClass::InnerClass<T> while gcc <= 5 was fine.

Please note that clang doesn't build this either, in any version, unless I
uncomment the first two lines. In either cases, it doesn't work with gcc 6.

Is this a gcc bug ? Or is this invalid C++ ?

Cheers,
Romain

Reply via email to