returning pointer to template objects in nested template classes

Discussion in 'C++' started by Javier Montoya, Nov 18, 2010.

  1. Hi everybody!

    I've two template classes, say Bar<S> and Foo<T>. Inside of the Foo<T>
    I've a method that returns Bar<S>*. After compiling the code, I get an
    error of:
    error: no matching function for call to
    ‘CBar<float>::doSomething(int&)’
    make: *** [main] Error 1

    Does somebody has an idea about how could I solve the problem? Below
    the structure of my code:

    // bar.h
    #ifndef BAR_H
    #define BAR_H
    template < class S >
    class Bar{
    ....
    };
    #endif

    // bar.cpp
    #include <bar.h>
    ....
    ....
    #include "bar-impl.inc"

    // bar-impl.inc
    template class Bar<int>;
    template class Bar<float>;

    // foo.h
    #ifndef FOO_H
    #define FOO_H
    #include <bar.h>
    template < class T >
    class Foo{
    public:
    .....
    int getSomething(int);
    ....
    template <class BarType>
    BarType * doSomething(int);
    ....
    };
    #endif

    // foo.cpp
    #include <foo.h>
    .....
    template < class T >
    template <class BarType>
    BarType * Foo<T>::doSomething(int idx){
    int num = this->getSomething(idx);
    BarType * pBar = new BarType(num);
    return pBar;
    }
    .......
    #include "foo-impl.inc"

    // foo-impl.inc
    template class Foo<int>;
    template class Foo<float>;
    template Bar<float> * Foo<int>::doSomething(int);
    template Bar<float> * Foo<float>::doSomething(int);

    // main.cpp
    #include <bar.h>
    #include <foo.h>

    int main(){
    Bar<float> * pBar = NULL;
    int num=4;
    Foo<float> * pFoo = new Foo<float>();
    pBar = pFoo->doSomething(num);

    return (0);
    }
     
    Javier Montoya, Nov 18, 2010
    #1
    1. Advertising

  2. Javier Montoya wrote:

    > Hi everybody!
    >
    > I've two template classes, say Bar<S> and Foo<T>. Inside of the Foo<T>
    > I've a method that returns Bar<S>*. After compiling the code, I get an
    > error of:
    > error: no matching function for call to
    > ‘CBar<float>::doSomething(int&)’
    > make: *** [main] Error 1
    >
    > Does somebody has an idea about how could I solve the problem? Below
    > the structure of my code:
    >
    > // bar.h
    > #ifndef BAR_H
    > #define BAR_H
    > template < class S >
    > class Bar{
    > ....
    > };
    > #endif
    >

    (impl skipped)
    > // foo.h
    > #ifndef FOO_H
    > #define FOO_H
    > #include <bar.h>
    > template < class T >
    > class Foo{
    > public:
    > ....
    > int getSomething(int);
    > ...
    > template <class BarType>
    > BarType * doSomething(int);
    > ...
    > };
    > #endif
    >

    (impl skipped)
    > // main.cpp
    > #include <bar.h>
    > #include <foo.h>
    >
    > int main(){
    > Bar<float> * pBar = NULL;
    > int num=4;
    > Foo<float> * pFoo = new Foo<float>();
    > pBar = pFoo->doSomething(num);

    There is a problem in your usage of Foo<float>::doSomething.
    Foo<float>::doSomething is a function template but there aren't any
    parameters which enable the compiler to guess what BarType is (remember, the
    return type is *not* used in guessing the template parameters). Therefore,
    the compiler cannot select a suitable BarType and generate an error.
    >
    > return (0);
    > }
     
    Michael Tsang, Nov 18, 2010
    #2
    1. Advertising

  3. On Nov 18, 4:02 pm, Michael Tsang <> wrote:
    > Javier Montoya wrote:
    > > Hi everybody!

    >
    > > I've two template classes, say Bar<S> and Foo<T>. Inside of the Foo<T>
    > > I've a method that returns Bar<S>*. After compiling the code, I get an
    > > error of:
    > > error: no matching function for call to
    > > ‘CBar<float>::doSomething(int&)’
    > > make: *** [main] Error 1

    >
    > > Does somebody has an idea about how could I solve the problem? Below
    > > the structure of my code:

    >
    > > // bar.h
    > > #ifndef BAR_H
    > > #define BAR_H
    > > template < class S >
    > > class Bar{
    > >   ....
    > > };
    > > #endif

    >
    > (impl skipped)
    > > // foo.h
    > > #ifndef FOO_H
    > > #define FOO_H
    > > #include <bar.h>
    > > template < class T >
    > > class Foo{
    > > public:
    > > ....
    > > int getSomething(int);
    > > ...
    > > template <class BarType>
    > > BarType * doSomething(int);
    > > ...
    > > };
    > > #endif

    >
    > (impl skipped)
    > > // main.cpp
    > > #include <bar.h>
    > > #include <foo.h>

    >
    > > int main(){
    > > Bar<float> * pBar = NULL;
    > > int num=4;
    > > Foo<float> * pFoo = new Foo<float>();
    > > pBar = pFoo->doSomething(num);

    >
    > There is a problem in your usage of Foo<float>::doSomething.
    > Foo<float>::doSomething is a function template but there aren't any
    > parameters which enable the compiler to guess what BarType is (remember, the
    > return type is *not* used in guessing the template parameters). Therefore,
    > the compiler cannot select a suitable BarType and generate an error.
    >
    >
    >
    > > return (0);
    > > }

    >
    >


    Thanks Michael! so the only solution would be to pass "BarType *" as a
    parameter, right? or is there any other possible solution:

    template < class T >
    class Foo{
    public:
    .....
    int getSomething(int);
    ....
    template <class BarType>
    void doSomething(int, BarType *);
    ....
    };

    Best
     
    Javier Montoya, Nov 18, 2010
    #3
  4. Javier Montoya

    Alen Wesker Guest

    Try to put this line into your Foo.cpp:
    #include "bar-impl.inc"

    You have seperated the implementation and the declaration of the Bar
    Template, haven't you?

    In this situation, the declaration h file could not substitute the
    real implementation, and the compiler would refuse to work until it
    sees the real implementation when it try to expland the Bar code. It
    is discused in the book <C++ Template>.

    I am not quit sure about the situation, maybe you can try what I said
    at first.
     
    Alen Wesker, Nov 19, 2010
    #4
  5. Javier Montoya

    Ali_Raz Guest

    On Nov 18, 10:17 am, Javier Montoya <> wrote:
    > On Nov 18, 4:02 pm, Michael Tsang <> wrote:
    >
    >
    >
    > > Javier Montoya wrote:
    > > > Hi everybody!

    >
    > > > I've two template classes, say Bar<S> and Foo<T>. Inside of the Foo<T>
    > > > I've a method that returns Bar<S>*. After compiling the code, I get an
    > > > error of:
    > > > error: no matching function for call to
    > > > ‘CBar<float>::doSomething(int&)’
    > > > make: *** [main] Error 1

    >
    > > > Does somebody has an idea about how could I solve the problem? Below
    > > > the structure of my code:

    >
    > > > // bar.h
    > > > #ifndef BAR_H
    > > > #define BAR_H
    > > > template < class S >
    > > > class Bar{
    > > >   ....
    > > > };
    > > > #endif

    >
    > > (impl skipped)
    > > > // foo.h
    > > > #ifndef FOO_H
    > > > #define FOO_H
    > > > #include <bar.h>
    > > > template < class T >
    > > > class Foo{
    > > > public:
    > > > ....
    > > > int getSomething(int);
    > > > ...
    > > > template <class BarType>
    > > > BarType * doSomething(int);
    > > > ...
    > > > };
    > > > #endif

    >
    > > (impl skipped)
    > > > // main.cpp
    > > > #include <bar.h>
    > > > #include <foo.h>

    >
    > > > int main(){
    > > > Bar<float> * pBar = NULL;
    > > > int num=4;
    > > > Foo<float> * pFoo = new Foo<float>();
    > > > pBar = pFoo->doSomething(num);

    >
    > > There is a problem in your usage of Foo<float>::doSomething.
    > > Foo<float>::doSomething is a function template but there aren't any
    > > parameters which enable the compiler to guess what BarType is (remember, the
    > > return type is *not* used in guessing the template parameters). Therefore,
    > > the compiler cannot select a suitable BarType and generate an error.

    >
    > > > return (0);
    > > > }

    >
    > Thanks Michael! so the only solution would be to pass "BarType *" as a
    > parameter, right? or is there any other possible solution:


    No, that's not a good solution. You can use explicit instantiation,
    e.g., pBar->doSomething<Bar<float> >(num); Note that you may need to
    use the template keyword if your calling code resides in a template,
    that is, pBar->template doSomething<Bar<float> >(num).
    >
    > template < class T >
    > class Foo{
    > public:
    > ....
    > int getSomething(int);
    > ...
    > template <class BarType>
    > void doSomething(int, BarType *);
    > ...
    >
    > };
    >
    > Best
     
    Ali_Raz, Nov 20, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Razvan
    Replies:
    5
    Views:
    11,316
    Dale King
    Jul 27, 2004
  2. kelvSYC
    Replies:
    2
    Views:
    598
    Chris Smith
    Aug 18, 2004
  3. Chad E. Dollins
    Replies:
    3
    Views:
    661
    Kai-Uwe Bux
    Nov 8, 2005
  4. Replies:
    2
    Views:
    546
  5. Alex
    Replies:
    3
    Views:
    90
Loading...

Share This Page