About the instantiation of a template class

Discussion in 'C++' started by =?gb2312?B?wfXquw==?=, Oct 12, 2007.

  1. Hi, folks,
    I'm running into a question as below:

    template<typename T>
    class A {
    private:
    T _a;
    public:
    A(T t): _a(t) {
    }
    };

    template<typename T>
    void operator+(A<T> lhs, A<T> rhs) {
    }

    int main() {
    A<int> obj(5);
    int t = 5;
    obj + t;
    }

    When I try to compile the code above under MSVC8, I got the following
    errors:

    1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
    template argument for 'A<T>' from 'int'

    2. error C2676: binary '+' : 'A<T>' does not define this operator or a
    conversion to a type acceptable to the predefined operator
    with
    [
    T=int
    ]

    Any informative reply will be appreciated, thanks in advance.

    Best regards,
    Liu Hao
     
    =?gb2312?B?wfXquw==?=, Oct 12, 2007
    #1
    1. Advertising

  2. =?gb2312?B?wfXquw==?=

    Adam Nielsen Guest

    Hi Liu Hao,

    > void operator+(A<T> lhs, A<T> rhs) {


    This function takes two objects of the A class.

    > obj + t;


    But here you're calling operator+ with one A object and one int.

    > 1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
    > template argument for 'A<T>' from 'int'


    The compiler is complaining that it doesn't know how to convert an int
    into an A<something> object.

    If you used two A objects it would work:

    A<int> obj(5);
    A<int> obj2(5);
    obj + obj2;

    You could also rewrite your + operator so that the object doesn't need
    to be an instance of A<something>:

    void operator+(A<T> lhs, T rhs)

    Or alternatively it may be possible to define an operator that allows an
    int to be converted into an A<int> - sorry, I'm not sure of the exact
    syntax. (I would've thought the constructor would be called implicitly
    though - perhaps someone can enlighten us.)

    Cheers,
    Adam.
     
    Adam Nielsen, Oct 12, 2007
    #2
    1. Advertising

  3. =?gb2312?B?wfXquw==?=

    Guest Guest

    On 10 12 , 10 31 , Adam Nielsen <>
    wrote:
    > Hi Liu Hao,
    >
    > > void operator+(A<T> lhs, A<T> rhs) {

    >
    > This function takes two objects of the A class.
    >
    > > obj + t;

    >
    > But here you're calling operator+ with one A object and one int.
    > > >
    > > >I think here the compiler is invoking the constructor A(int t) of class A<int>, thus got an temporary A<int> object.
    > > >

    >
    > > 1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
    > > template argument for 'A<T>' from 'int'

    >
    > The compiler is complaining that it doesn't know how to convert an int
    > into an A<something> object.
    >
    > If you used two A objects it would work:
    >
    > A<int> obj(5);
    > A<int> obj2(5);
    > obj + obj2;
    >
    > You could also rewrite your + operator so that the object doesn't need
    > to be an instance of A<something>:
    >
    > void operator+(A<T> lhs, T rhs)
    >
    > Or alternatively it may be possible to define an operator that allows an
    > int to be converted into an A<int> - sorry, I'm not sure of the exact
    > syntax. (I would've thought the constructor would be called implicitly
    > though - perhaps someone can enlighten us.)
    >
    > Cheers,
    > Adam.
     
    Guest, Oct 12, 2007
    #3
  4. =?gb2312?B?wfXquw==?=

    James Kanze Guest

    On Oct 12, 4:31 am, Adam Nielsen <>
    wrote:

    > > void operator+(A<T> lhs, A<T> rhs) {


    > This function takes two objects of the A class.


    This is not a function, but a template. It only becomes a
    function when instantiated.

    > > obj + t;


    > But here you're calling operator+ with one A object and one int.


    Here, you're asking the compiler to deduce the types for the
    above template, and instantiate it using the deduced types.

    > > 1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
    > > template argument for 'A<T>' from 'int'


    > The compiler is complaining that it doesn't know how to convert an int
    > into an A<something> object.


    No. The compiler knows how to convert an int into an A<int>
    object, which is what is wanted. The problem here is that the
    rules for type deduction do not allow the compiler to deduce the
    arguments for the operator+ template, so it cannot instantiate
    the function.

    > If you used two A objects it would work:


    > A<int> obj(5);
    > A<int> obj2(5);
    > obj + obj2;


    > You could also rewrite your + operator so that the object
    > doesn't need to be an instance of A<something>:


    > void operator+(A<T> lhs, T rhs)


    > Or alternatively it may be possible to define an operator that
    > allows an int to be converted into an A<int> - sorry, I'm not
    > sure of the exact syntax. (I would've thought the constructor
    > would be called implicitly though - perhaps someone can
    > enlighten us.)


    The usual solution here would be something along the lines of:

    template< typename T >
    class A
    : public Operators< A< T > >
    , public MixedOperators< A< T >, T >
    {
    public:
    // ...
    A& operator+=( A const& other ) ;
    } ;

    with the usual definitions for Operators and MixedOperators:

    template< typename T >
    class Operators
    {
    public:
    friend T operator+( T const& lhs, T const& rhs )
    {
    T result( lhs ) ;
    result += rhs ;
    return result ;
    }
    // And so on for the other operators...
    } ;

    template< typename T1, typename T2 >
    class MixedOperators
    {
    public:
    friend T1 operator+( T1 const& lhs, T2 const& rhs )
    {
    T1 result( lhs ) ;
    result += rhs ; // Note that here, template
    // type deduction isn't needed,
    // so the compiler will find
    // any necessary conversions.
    return result ;
    }
    // And so on for the other operators...
    friend T1 operator+( T2 const& lhs, T1 const& rhs )
    {
    T1 result( rhs ) ;
    result += lhs ;
    return result ;
    }
    // And so on for the other commutative operators...
    } ;

    (Note that in this solution, there are no function
    templates:).)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Oct 12, 2007
    #4
    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. Fernando Cuenca
    Replies:
    4
    Views:
    2,529
    Gianni Mariani
    Sep 6, 2004
  2. christopher diggins
    Replies:
    16
    Views:
    756
    Pete Becker
    May 4, 2005
  3. Replies:
    1
    Views:
    580
    Salt_Peter
    Dec 25, 2006
  4. Ed
    Replies:
    1
    Views:
    349
  5. Noah Roberts
    Replies:
    6
    Views:
    1,171
    Johannes Schaub (litb)
    Feb 2, 2011
Loading...

Share This Page