How to get address of templated object?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • RRick
    Recognized Expert Contributor
    • Feb 2007
    • 463

    How to get address of templated object?

    This is a problem that arose while using GNU G++3.4.5. The problem is simple: How to get a pointer value from a templated object inside a class? Normally, I would add an '&' can carry on. This does not seem to work.

    Take a look at the example and some of the things I tried. There are only two classes, Base and Derived, where Base defines the buffer, and Derived tries to set a pointer to it.

    If you take away the template specification, everything works like it should.

    Any ideas?

    Rick

    Code:
    template <typename CharT>
    class  Base
    {
    public:
        CharT  buffer_;
    };
    
    
    template <typename CharT>
    class  Derived:   public Base<CharT>
    {
    public:
        Derived( void)
        {   
            CharT * ptr =  & buffer_;   // error: `buffer_' was not declared in this scope
            CharT * ptr =  & Base<CharT>::buffer_;  // error: cannot convert `char Base<char>::*' to `char*' in initialization 
            CharT * ptr =  & (Base<CharT>::buffer_); // error:  same as last one
    
            // This works but sure is ugly
            CharT & ref =  Base<CharT>::buffer_;
            CharT * ptr = & ref;
        }
    };
    
    
    int main( void)
    {
        Derived<char> dah;
    }
  • AdrianH
    Recognized Expert Top Contributor
    • Feb 2007
    • 1251

    #2
    Originally posted by RRick
    This is a problem that arose while using GNU G++3.4.5. The problem is simple: How to get a pointer value from a templated object inside a class? Normally, I would add an '&' can carry on. This does not seem to work.

    Take a look at the example and some of the things I tried. There are only two classes, Base and Derived, where Base defines the buffer, and Derived tries to set a pointer to it.

    If you take away the template specification, everything works like it should.

    Any ideas?

    Rick

    Code:
    template <typename CharT>
    class  Base
    {
    public:
        CharT  buffer_;
    };
    
    
    template <typename CharT>
    class  Derived:   public Base<CharT>
    {
    public:
        Derived( void)
        {   
            CharT * ptr =  & buffer_;   // error: `buffer_' was not declared in this scope
            CharT * ptr =  & Base<CharT>::buffer_;  // error: cannot convert `char Base<char>::*' to `char*' in initialization 
            CharT * ptr =  & (Base<CharT>::buffer_); // error:  same as last one
    
            // This works but sure is ugly
            CharT & ref =  Base<CharT>::buffer_;
            CharT * ptr = & ref;
        }
    };
    
    
    int main( void)
    {
        Derived<char> dah;
    }
    Yeah, I came across this reciently. A lazy way would be to use 'this->buffer_' to access derrived member. 'corse it won't work if you have a buffer_ declared in derrived class.

    Also, what is all the 'ptr's and 'ref's in your code for? That may have something to do with it.

    Hope this helps.


    Adrian

    Comment

    • AdrianH
      Recognized Expert Top Contributor
      • Feb 2007
      • 1251

      #3
      Originally posted by AdrianH
      Yeah, I came across this reciently. A lazy way would be to use 'this->buffer_' to access derrived member. 'corse it won't work if you have a buffer_ declared in derrived class.

      Also, what is all the 'ptr's and 'ref's in your code for? That may have something to do with it.

      Hope this helps.


      Adrian
      Ignore my question on the ptr's and ref's. I wasn't reading right.

      Anyway, yeah, use either this->buffer_ or get the reference to a var and get the address of that like you did. It is a little messy, but it doesn't add extra object (assembly) code then doing it directly.

      Hope this helps.


      Adrian

      Comment

      • RRick
        Recognized Expert Contributor
        • Feb 2007
        • 463

        #4
        This problem arose from a template constructor where I had to pass the pointer of a templated object found in the base class to another templated object found in the derived object. The real problem was getting the compiler to accept the pointer referencing. What you saw posted was the stripped down information.

        For some reason and in some cases, templates don't use the specialization information in derived classes when refering to some base class methods. As to the particular details of why this happens, I can't say. My eyes tend to glaze over in deep discussions about template instantiation and specialization.

        I did find out that the compiler can get speciaization information from the this pointer. I will remember "this" trick in the future.

        Comment

        • AdrianH
          Recognized Expert Top Contributor
          • Feb 2007
          • 1251

          #5
          Originally posted by RRick
          This problem arose from a template constructor where I had to pass the pointer of a templated object found in the base class to another templated object found in the derived object.
          Man, that sounds really convoluted. :)

          Originally posted by RRick
          The real problem was getting the compiler to accept the pointer referencing. What you saw posted was the stripped down information.
          Thank goodness. :D

          Originally posted by RRick
          For some reason and in some cases, templates don't use the specialization information in derived classes when refering to some base class methods. As to the particular details of why this happens, I can't say. My eyes tend to glaze over in deep discussions about template instantiation and specialization.
          Yeah, I can't understand it either. Why you can do it with a reference but not a pointer is beyond me.

          Originally posted by RRick
          I did find out that the compiler can get speciaization information from the this pointer. I will remember "this" trick in the future.
          Glad to have helped.

          Oh and I found another way of doing it:
          Code:
          CharT* ptr = &static_cast<CharT&>(Base<CharT>::buffer_);
          Messy eh? To get the pointer must be due to a parsing problem.


          Adrian

          Comment

          • RRick
            Recognized Expert Contributor
            • Feb 2007
            • 463

            #6
            This problem arose from trying to modify an ostream by supplying it with another streambuffer. Before we go too far, realize that a very nice book (C++ Standard Library by Josuttis) did all the hard work; I just copied his solution. Specifically, I needed a streambuffer that could handle unix file descriptors (i.e. for pipes, sockets, etc.), Gnu has some extensions for this, but I needed something for more than one compiler.

            I've never looked at the c++ io objects very closely (mainly due to fear) but they have a nice design. They break IO into formatting and device control. The ios objects deal with formatting and the streambuffer objects deal with the device. If you look at ostream, it is simply a char instantiation of basic_ostream with a "pointer" to a basic_streambuf f. That's where the trouble started. I had a class derived from basis_ostream, that needed to pass a pointer to a derived streambuffer to the base class. Its the crossing from derived to base class that caused the problem (I think).

            Comment

            Working...