http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54137

             Bug #: 54137
           Summary: expected primary-expression error when accessing
                    template method
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: vagran....@gmail.com


Created attachment 27905
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27905
Source, preprocessed source, compilation log.

When compiling the code snippet below (preprocessed source is also attached) I
have the following errors:

test.cpp: In member function ‘DerivedObject<T>::Item*
DerivedObject<T>::CreateItem()’:
test.cpp:41:53: error: expected primary-expression before ‘>’ token
test.cpp:41:55: error: expected primary-expression before ‘)’ token

The main reason I suspect it is a bug is the fact that after replacing line 41
<<< return GetFabric().CreateObject<Item>();
=== by
>>> Fabric &f = GetFabric();
>>> return f.CreateObject<Item>();
it compiles and works as expected.

I have tried to minimize the code to just reflect inheritance graph in the
place where the problem was found.

#include <utility>

class Fabric {
public:
    template <class T, typename... Args>
    T *
    CreateObject(Args&&... args)
    {
        return new T(std::forward<Args>(args)...);
    }

    template <class T>
    T *
    CreateObject()
    {
        return new T;
    }
};

class Object {
public:
    Fabric f;

    Fabric &
    GetFabric()
    {
        return f;
    }
};

template <class T>
class DerivedObject: public Object {
public:
    class Item: public Object {
        T item;
    };

    Item *
    CreateItem()
    {
        return GetFabric().CreateObject<Item>();
        // The commented lines below do not produce any errors:
        // Fabric &f = GetFabric();
        // return f.CreateObject<Item>();
    }
};

int 
main()
{
    DerivedObject<int> d;
    d.CreateItem();
    return 0;
}

Reply via email to