Accessing the function pointer type of the base template classes

I have a class that was provided that I really don't want to change, but I want to extend it. I am a template model and newbie experimenting with a Decorator pattern applied to a template class. The template class contains a member pointer (if I understand the semantics correctly) in another class. Pointer-to-member is an XML stream deserializer. Type "T" is the type of XML document to be deserialized.

template <typename T> class B {
public:
  typedef std::auto_ptr<T> MYFUN( 
    std::istream&, const std::string&, const std::string& );

public:
  B<T>( MYFUN* p );

private:
  MYFUN *fptr;
  std::string aString1;
  std::string aString2;

      

};

The typedef looks strange to me after reading http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5 and still this class works fine as it is. There are no additional #defines in the provided header file, so this is a bit cryptic to me.

Now I'm trying to extend it like Decorator because I want to do a little work on the auto_ptr object returned by MYFUN:

template <typename T>
class D : public class B<T>
{
  D( B<T>::MYFUN *fPtr, B<T> *providedBase ); //compiler complaint
  //Looks like B
  private:
    B* base_;

};

template <typename T>
D<T>::D( B<T>::MYFUN *p, B<T> *base ) //compiler complaint
:
B<T>::B( p ), base_(providedBase)
{ }

      

When trying to compile this, I get a syntax complaint on the two lines mentioned. An error is something like "expected") "at *". There is no complaint that MYFUN is undefined.

When I override an element pointer in D with the same signature as in D, i.e.

//change MYFUN to NEWFUN in D)
typedef std::auto_ptr<T> MYNEWFUN( 
    std::istream&, const std::string&, const std::string& );

      

It works. I prefer not to do this for every D / Decorator I can make from B. I tried to typedef more globally but couldn't get the syntax on the right because of the undefined template parameter.

+1


a source to share


3 answers


The compilation error is due to the fact that the compiler cannot tell what you are talking about the type.

Try:

D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );

      



and

template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )

      

See the Templates section in the C ++ FAQ Lite for more details on why this is needed, but the summary is that due to the possibility of template specialization, the compiler cannot be sure what is B<T>::MYFUN

actually referring to a type.

0


a source


The definition of MYPUN typedef in B is done with private visibility. D won't be able to access it. If you change it to protected or open, does it work?



template <typename T> class B {
  protected:
    typedef std::auto_ptr<T> MYFUN( 
      std::istream&, const std::string&, const std::string& );
...
};

      

+1


a source


The problem I see with this is that B :: MYFUN is a private typedef.

Hence, any inheriting class cannot access it.

Change this to:

template <typename T> class B 
{  
public:
   typedef std::auto_ptr<T> MYFUN(     std::istream&, const std::string&, const std::string& );
public:  
   B<T>( MYFUN* p );
private:  
   MYFUN *fptr;  
std::string aString1;  
std::string aString2;
};

      

0


a source







All Articles