templates and inheritance

Discussion in 'C++' started by er, Sep 18, 2007.

  1. er

    er Guest

    i have

    class Impl; //abstract
    class Impl_A:public Impl{...};//abstract
    class Impl_B:public Impl{...};//abstract
    class Impl_A_0: public Impl_A{/* implements */};

    class S{ public: S(Impl*,...); ...};
    class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    //hierarchy ends here

    template<typename T,typename U>
    std::vector<U> mult(T* pimpl){
    //calls U(pimpl,...);
    };

    a) std::vector<S_A> vec(mult<Impl_A0*,S_A>(Impl_A0*)); //ok
    b) std::vector<S_A> vec(mult(Impl_A0*)); //compiler error: no
    matching function

    i would have thought that T and U are implicitly specified by the
    input and return type, respectively, so that b) would work?

    Overloading like this does not work because i loose information about
    the leaf class (Impl_A0* in example):
    std::vector<S_A> mult_A(Impl_A* pimpl){return mult(pimpl);}
    std::vector<S_B> mult_A(Impl_B* pimpl){return mult(pimpl);}

    any suggestion?
    er, Sep 18, 2007
    #1
    1. Advertising

  2. er wrote:
    > i have
    >
    > class Impl; //abstract
    > class Impl_A:public Impl{...};//abstract
    > class Impl_B:public Impl{...};//abstract
    > class Impl_A_0: public Impl_A{/* implements */};
    >
    > class S{ public: S(Impl*,...); ...};
    > class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    > class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    > //hierarchy ends here
    >
    > template<typename T,typename U>
    > std::vector<U> mult(T* pimpl){
    > //calls U(pimpl,...);
    > };
    >
    > a) std::vector<S_A> vec(mult<Impl_A0*,S_A>(Impl_A0*)); //ok


    OK -- what? 'vec' is a declaration of a function here, methinks.

    > b) std::vector<S_A> vec(mult(Impl_A0*)); //compiler error: no
    > matching function
    >
    > i would have thought that T and U are implicitly specified by the
    > input and return type, respectively, so that b) would work?


    'vec' has overloaded constructors. How should the compiler know
    that you intend to use the copy constructor? Yes, if it knew that
    the intended specialisation of 'mult' returns a 'vec<S_A>', then
    it might figure out that the copy c-tor is needed. But to know
    what 'mult' to specialise (and how), it needs to know what your
    'vec' constructor accepts as the argument. The classic catch-22.

    > Overloading like this does not work because i loose information about
    > the leaf class (Impl_A0* in example):
    > std::vector<S_A> mult_A(Impl_A* pimpl){return mult(pimpl);}
    > std::vector<S_B> mult_A(Impl_B* pimpl){return mult(pimpl);}
    >
    > any suggestion?


    What exactly are you trying to accomplish?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 18, 2007
    #2
    1. Advertising

  3. er

    er Guest

    On Sep 18, 6:39 pm, "Victor Bazarov" <> wrote:
    > er wrote:
    > > i have

    >
    > > class Impl; //abstract
    > > class Impl_A:public Impl{...};//abstract
    > > class Impl_B:public Impl{...};//abstract
    > > class Impl_A_0: public Impl_A{/* implements */};

    >
    > > class S{ public: S(Impl*,...); ...};
    > > class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    > > class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    > > //hierarchy ends here

    >
    > > template<typename T,typename U>
    > > std::vector<U> mult(T* pimpl){
    > > //calls U(pimpl,...);
    > > };

    >
    > > a) std::vector<S_A> vec(mult<Impl_A0*,S_A>(Impl_A0*)); //ok

    >
    > OK -- what? 'vec' is a declaration of a function here, methinks.
    >
    > > b) std::vector<S_A> vec(mult(Impl_A0*)); //compiler error: no
    > > matching function

    >
    > > i would have thought that T and U are implicitly specified by the
    > > input and return type, respectively, so that b) would work?

    >
    > 'vec' has overloaded constructors. How should the compiler know
    > that you intend to use the copy constructor? Yes, if it knew that
    > the intended specialisation of 'mult' returns a 'vec<S_A>', then
    > it might figure out that the copy c-tor is needed. But to know
    > what 'mult' to specialise (and how), it needs to know what your
    > 'vec' constructor accepts as the argument. The classic catch-22.
    >
    > > Overloading like this does not work because i loose information about
    > > the leaf class (Impl_A0* in example):
    > > std::vector<S_A> mult_A(Impl_A* pimpl){return mult(pimpl);}
    > > std::vector<S_B> mult_A(Impl_B* pimpl){return mult(pimpl);}

    >
    > > any suggestion?

    >
    > What exactly are you trying to accomplish?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    perhaps i should clarify that vec is the name i give to my vector that
    i initialize with the output from mult.
    er, Sep 18, 2007
    #3
  4. er wrote:
    > On Sep 18, 6:39 pm, "Victor Bazarov" <> wrote:
    >> er wrote:
    >>> i have

    >>
    >>> class Impl; //abstract
    >>> class Impl_A:public Impl{...};//abstract
    >>> class Impl_B:public Impl{...};//abstract
    >>> class Impl_A_0: public Impl_A{/* implements */};

    >>
    >>> class S{ public: S(Impl*,...); ...};
    >>> class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    >>> class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    >>> //hierarchy ends here

    >>
    >>> template<typename T,typename U>
    >>> std::vector<U> mult(T* pimpl){
    >>> //calls U(pimpl,...);
    >>> };

    >>
    >>> a) std::vector<S_A> vec(mult<Impl_A0*,S_A>(Impl_A0*)); //ok

    >>
    >> OK -- what? 'vec' is a declaration of a function here, methinks.
    >>
    >>> b) std::vector<S_A> vec(mult(Impl_A0*)); //compiler error: no
    >>> matching function

    >>
    >>> i would have thought that T and U are implicitly specified by the
    >>> input and return type, respectively, so that b) would work?

    >>
    >> 'vec' has overloaded constructors. How should the compiler know
    >> that you intend to use the copy constructor? Yes, if it knew that
    >> the intended specialisation of 'mult' returns a 'vec<S_A>', then
    >> it might figure out that the copy c-tor is needed. But to know
    >> what 'mult' to specialise (and how), it needs to know what your
    >> 'vec' constructor accepts as the argument. The classic catch-22.
    >>
    >>> Overloading like this does not work because i loose information
    >>> about the leaf class (Impl_A0* in example):
    >>> std::vector<S_A> mult_A(Impl_A* pimpl){return mult(pimpl);}
    >>> std::vector<S_B> mult_A(Impl_B* pimpl){return mult(pimpl);}

    >>
    >>> any suggestion?

    >>
    >> What exactly are you trying to accomplish?
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > perhaps i should clarify that vec is the name i give to my vector that
    > i initialize with the output from mult.


    The statement

    vector<int> vec(mult(char*));

    is not a declaration of a vector. And if 'mult' is a function, it is
    a syntax error because a type is passed to the function instead of
    a value.

    Please follow the recommendations of FAQ 5.8.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 19, 2007
    #4
  5. er

    er Guest

    On Sep 18, 7:07 pm, "Victor Bazarov" <> wrote:
    > er wrote:
    > > On Sep 18, 6:39 pm, "Victor Bazarov" <> wrote:
    > >> er wrote:
    > >>> i have

    >
    > >>> class Impl; //abstract
    > >>> class Impl_A:public Impl{...};//abstract
    > >>> class Impl_B:public Impl{...};//abstract
    > >>> class Impl_A_0: public Impl_A{/* implements */};

    >
    > >>> class S{ public: S(Impl*,...); ...};
    > >>> class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    > >>> class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    > >>> //hierarchy ends here

    >
    > >>> template<typename T,typename U>
    > >>> std::vector<U> mult(T* pimpl){
    > >>> //calls U(pimpl,...);
    > >>> };

    >
    > >>> a) std::vector<S_A> vec(mult<Impl_A0*,S_A>(Impl_A0*)); //ok

    >
    > >> OK -- what? 'vec' is a declaration of a function here, methinks.

    >
    > >>> b) std::vector<S_A> vec(mult(Impl_A0*)); //compiler error: no
    > >>> matching function

    >
    > >>> i would have thought that T and U are implicitly specified by the
    > >>> input and return type, respectively, so that b) would work?

    >
    > >> 'vec' has overloaded constructors. How should the compiler know
    > >> that you intend to use the copy constructor? Yes, if it knew that
    > >> the intended specialisation of 'mult' returns a 'vec<S_A>', then
    > >> it might figure out that the copy c-tor is needed. But to know
    > >> what 'mult' to specialise (and how), it needs to know what your
    > >> 'vec' constructor accepts as the argument. The classic catch-22.

    >
    > >>> Overloading like this does not work because i loose information
    > >>> about the leaf class (Impl_A0* in example):
    > >>> std::vector<S_A> mult_A(Impl_A* pimpl){return mult(pimpl);}
    > >>> std::vector<S_B> mult_A(Impl_B* pimpl){return mult(pimpl);}

    >
    > >>> any suggestion?

    >
    > >> What exactly are you trying to accomplish?

    >
    > >> V
    > >> --
    > >> Please remove capital 'A's when replying by e-mail
    > >> I do not respond to top-posted replies, please don't ask

    >
    > > perhaps i should clarify that vec is the name i give to my vector that
    > > i initialize with the output from mult.

    >
    > The statement
    >
    > vector<int> vec(mult(char*));
    >
    > is not a declaration of a vector. And if 'mult' is a function, it is
    > a syntax error because a type is passed to the function instead of
    > a value.
    >
    > Please follow the recommendations of FAQ 5.8.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    ok, i see what you mean. please consider:

    ImplA0* pimpl=new Impl_A0;
    a) std::vector<S_A> vec=mult<Impl_A0,S_A>(pimpl); //ok
    b) std::vector<S_A> vec=mult(pimpl); //compiler error
    er, Sep 19, 2007
    #5
  6. er wrote:
    > On Sep 18, 7:07 pm, "Victor Bazarov" <> wrote:
    >> er wrote:
    >>> On Sep 18, 6:39 pm, "Victor Bazarov" <>
    >>> wrote:
    >>>> er wrote:
    >>>>> i have

    >>
    >>>>> class Impl; //abstract
    >>>>> class Impl_A:public Impl{...};//abstract
    >>>>> class Impl_B:public Impl{...};//abstract
    >>>>> class Impl_A_0: public Impl_A{/* implements */};

    >>
    >>>>> class S{ public: S(Impl*,...); ...};
    >>>>> class S_A: public S{ public: S_A(Impl_A* impl,...):S(impl){};
    >>>>> class S_B: public S{ public: S_B(Impl_B* impl,...):S(impl){};
    >>>>> //hierarchy ends here

    >>
    >>>>> template<typename T,typename U>
    >>>>> std::vector<U> mult(T* pimpl){
    >>>>> //calls U(pimpl,...);
    >>>>> };

    >> [..]

    >
    > ok, i see what you mean. please consider:
    >
    > ImplA0* pimpl=new Impl_A0;
    > a) std::vector<S_A> vec=mult<Impl_A0,S_A>(pimpl); //ok
    > b) std::vector<S_A> vec=mult(pimpl); //compiler error


    Change your 'mult' definition to

    template<class U, class T>
    std::vector<U> mult(T* pimpl) { ...

    Then you could do

    std::vector<S_A> vec = mult<S_A>(pimpl);

    The reason it won't work without <S_A> after 'mult' is that
    you cannot expect the compiler to deduce the 'U' type without
    the argument and unclear return value type (see my mention
    of 'catch-22' earlier). The deduction of the template return
    value type can only successfully happen if a function pointer
    is initialised from a template:

    vector<int> (*pf)(char*) = mult;

    (should deduce 'U' as 'int' and 'T' as 'char').

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 19, 2007
    #6
    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. JKop
    Replies:
    3
    Views:
    453
  2. Generic Usenet Account
    Replies:
    3
    Views:
    799
    Generic Usenet Account
    Jul 14, 2005
  3. BigMan
    Replies:
    1
    Views:
    425
  4. recover
    Replies:
    2
    Views:
    788
    recover
    Jul 25, 2006
  5. Rouslan Korneychuk
    Replies:
    8
    Views:
    588
    Rouslan Korneychuk
    Feb 10, 2011
Loading...

Share This Page