public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "johill at lanl dot gov" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/21665] New: template template parameter function overload not recognized
Date: Thu, 19 May 2005 14:21:00 -0000	[thread overview]
Message-ID: <20050519141941.21665.johill@lanl.gov> (raw)

The following does not compile with g++ 3.4.2 on Solaris and 3.2.3 on Linux, but
probably should, and does with other compilers.

class PropertyId;
class ArraySegment;
class StringSegment;
class EnumStateSet;
class PropertyCatalog;
class PropertyCatalog;
class Time;

class PropertyId {
};

extern class PropertyCatalog & voidContainer;

template < template < class T > class PROPERTY >
class PropertyManipulator {
public:
    virtual void reveal ( PROPERTY < float > & )  = 0;
    virtual void reveal ( PROPERTY < double > & )  = 0;
    virtual void reveal ( PROPERTY < char > & ) = 0; 
    virtual void reveal ( PROPERTY < signed char > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned char > & ) = 0; 
    virtual void reveal ( PROPERTY < short > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned short > & ) = 0; 
    virtual void reveal ( PROPERTY < int > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned int > & ) = 0; 
    virtual void reveal ( PROPERTY < long > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned long > & ) = 0; 
    virtual void reveal ( PROPERTY < Time > & ) = 0; 
    virtual void reveal ( PROPERTY < StringSegment > & ) = 0; 
    virtual void reveal ( PROPERTY < EnumStateSet > & ) = 0; 
    virtual void reveal ( PROPERTY < ArraySegment > & ) = 0; 
    virtual void reveal ( PROPERTY < PropertyCatalog > & ) = 0; 
};

template < class CATALOG > 
class PropertyBase {
public:
    PropertyBase ( 
        const PropertyId & id, CATALOG & subordinate );
    const PropertyId & id () const;
    CATALOG & subordinate () const;
private:
    const PropertyId & _id;
    CATALOG & _subordinateProperties;
};

template < class T > 
class PropertyType : public PropertyBase < const PropertyCatalog > {
public:
    PropertyType ( const PropertyId & id,  
        const PropertyCatalog & = voidContainer );
    template < class C >
    PropertyType ( 
        const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate = voidContainer );
};

template < class T > 
class PropertyMutable : public PropertyBase < PropertyCatalog > {
public:
    PropertyMutable ( 
        const PropertyId & id, T & value,  
        PropertyCatalog & subordinate = voidContainer );
    template < class C >
    PropertyMutable ( 
        const PropertyId & id, C * pC, T ( C :: * p ), 
        PropertyCatalog & subordinate = voidContainer );
    T & value ();
private:
    T & _scalar;
};

template < class T > 
class PropertyImmutable : public PropertyBase < const PropertyCatalog > {
public:
    PropertyImmutable ( 
        const PropertyId & id, const T & value,  
        const PropertyCatalog & subordinate = voidContainer );
    template < class C >
    PropertyImmutable ( 
        const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate = voidContainer );
    const T & value () const;
private:
    const T & _scalar;
};

class PropertySkeleton {
public:
    virtual void traverse ( 
        PropertyManipulator < PropertyType > & ) = 0;
};

class PropertyCatalog {
public:
    virtual void traverse ( 
        PropertyManipulator < PropertyMutable > & ) = 0;
    virtual void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const = 0;
    // false returned when the property does not exist, otherwise true
    virtual bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & )
const = 0;
};

// ----------------- begin property implementation
----------------------------------

class VoidContainer : public PropertyCatalog {
    void traverse ( 
        PropertyManipulator < PropertyMutable > & ) {}
    void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const {}
    // false returned when the property does not exist, otherwise true
    bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & ) const 
    {
        return false;
    }
};

VoidContainer aVoidContainer;

class PropertyCatalog & voidContainer = aVoidContainer;

template < class CATALOG > 
inline PropertyBase < CATALOG > :: PropertyBase ( 
    const PropertyId & id, CATALOG & subordinate ) :
        _id ( id ), _subordinateProperties ( subordinate )
{
}

template < class CATALOG > 
inline const PropertyId & PropertyBase < CATALOG > :: id () const
{
    return _id;
}

template < class CATALOG > 
inline CATALOG & PropertyBase < CATALOG > :: subordinate () const
{
    return _subordinateProperties;
}

template < class T > 
inline PropertyType < T > :: PropertyType ( 
        const PropertyId & id, 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate )
{
}
        
template < class T > template < class C >
inline PropertyType < T > :: PropertyType ( 
    const PropertyId & id, const C *, T ( C :: * ), 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate )
{
}

template < class T > 
inline PropertyMutable < T > :: PropertyMutable ( 
        const PropertyId & id, T & value, PropertyCatalog & subordinate ) :
    PropertyBase < PropertyCatalog > ( id, subordinate ), _scalar ( value )
{
}

template < class T > template < class C >
inline PropertyMutable < T > :: PropertyMutable ( 
    const PropertyId & id, C * pC, T ( C :: * p ), 
        PropertyCatalog & subordinate ) :
    PropertyBase < PropertyCatalog > ( id, subordinate ), _scalar ( pC->*p )
{
}

template < class T > 
inline T & PropertyMutable < T > :: value () 
{
    return _scalar;
}

template < class T > 
inline PropertyImmutable < T > :: PropertyImmutable ( 
        const PropertyId & id, const T & value,  
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate ), _scalar ( value )
{
}

template < class T > template < class C >
inline PropertyImmutable < T > :: PropertyImmutable ( 
    const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate ), _scalar ( pC->*p )
{
}

template < class T > 
inline const T & PropertyImmutable < T > :: value () const
{
    return _scalar;
}

// --------------------------- begin application specific -------------

PropertyId propertyX;
PropertyId propertyY;

class MyContainerSkeleton : public PropertySkeleton {
public:
    void traverse ( 
        PropertyManipulator < PropertyType > & );
};

class MyContainer : 
    public PropertyCatalog, public MyContainerSkeleton {
public:
    void traverse ( 
        PropertyManipulator < PropertyMutable > & );
    void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const;
    static void traverseTypes ( 
        PropertyManipulator < PropertyType > & );
    bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & ) const;
private:
    int x;
    float y;
    template < class C, template < class T > class PROPERTY >
    static void traverseTempl ( 
        C * pContainer, PropertyManipulator < PROPERTY > & ); 
};

// C is a template purely so that we can reveal const and non-const 
// using the same template, but perhaps there is another way
template < class C, template < class T > class PROPERTY >
void MyContainer::traverseTempl ( 
    C * pContainer, PropertyManipulator < PROPERTY > & manipulator )
{
    manipulator.reveal ( 
	    PROPERTY < int > ( propertyX, pContainer, & MyContainer::x ) );
    manipulator.reveal ( 
	    PROPERTY < float > ( propertyY, pContainer, & MyContainer::y ) );
}

void MyContainer::traverse ( 
    PropertyManipulator < PropertyMutable > & manipulator ) 
{
    MyContainer::traverseTempl ( this, manipulator );
}

void MyContainer::traverse ( 
    PropertyManipulator < PropertyImmutable > & manipulator ) const 
{
    MyContainer::traverseTempl ( this, manipulator );
}

void MyContainerSkeleton::traverse ( 
    PropertyManipulator < PropertyType > & manipulator )
{
    MyContainer::traverseTypes ( manipulator );
}

void MyContainer::traverseTypes ( 
    PropertyManipulator < PropertyType > & manipulator )
{
    const MyContainer * pC = 0;
    MyContainer::traverseTempl ( pC, manipulator );
}

MyContainer mc;

-- 
           Summary: template template parameter function overload not
                    recognized
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: johill at lanl dot gov
                CC: gcc-bugs at gcc dot gnu dot org
  GCC host triplet: solaris/sparc also earlier version on Linux
GCC target triplet: solaris/sparc also earlier version on Linux


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


             reply	other threads:[~2005-05-19 14:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-19 14:21 johill at lanl dot gov [this message]
2005-05-19 14:39 ` [Bug c++/21665] " johill at lanl dot gov
2005-05-19 14:40 ` johill at lanl dot gov
2005-05-19 14:51 ` pinskia at gcc dot gnu dot org
2005-05-19 16:10 ` johill at lanl dot gov
2005-05-19 16:12 ` johill at lanl dot gov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050519141941.21665.johill@lanl.gov \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).