Template friend (unary and binary) operators

Discussion in 'C++' started by Ruben Campos, Nov 30, 2004.

  1. Ruben Campos

    Ruben Campos Guest

    Some questions about this code:

    template <typename T> class MyTemplate;
    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object);
    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object1, const MyTemplate <T> & object2);

    template <typename T>
    class MyTemplate
    {
    public:
    MyTemplate (const T & data = T()) : mData(data) {}
    MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}

    MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
    object.mData; return *this; }

    friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object);
    MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
    object.mData; return *this; }
    friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
    const MyTemplate <T> & object2);

    private:

    T mData;
    };

    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object) { return MyTemplate <T> (-object.mData); }
    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
    result -= object2; return result; }

    int
    main
    {
    MyTemplate <float> object1(1.0f);
    MyTemplate <float> object2(-object1);
    }

    a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
    unexpected token errors, first, and then some "new definition" errors for
    the friend operator-, saying me that it was previously defined as a member.
    In fact, unary operator- is defined as a member, and subsequently binary
    operator- is defined as a friend function. So, they are considered as the
    same function by the compiler? This doesn't make sense for me, because they
    have different parameters.

    In order to deal with this, I've tried two alternatives: a) changing the
    template MyTemplate <T> class for a non-template one, while keeping the
    unary member and binary friend operator-, and b) keep MyTemplate <T> as a
    template class, while changing member unary operator- for a friend one. In
    both cases, these errors don't appear, and the code compiles (and works)
    fine. So I know it is a fact which concern templates only. Is possible to
    include a unary member operator- and a binary friend operator- in the same
    template class?

    b) Nothing to do with the previous question, first constructor have a
    default parameter "const T & data = T()". When I instantiate MyTemplate
    <float> objects through this constructor, both in the stack and in the heap,
    mData is initialized to 0.0f value. Is this standard, being always all
    built-in types initialized to zero when their default constructor (exists?)
    is called (inside a template, for example)? Is this a coincidence, favoured
    by the involved memory contents at the construction time? Or is this
    compiler-dependent, implemented specifically by (in my case) MS Visual C++
    7.x?
    Ruben Campos, Nov 30, 2004
    #1
    1. Advertising

  2. Ruben Campos wrote:
    > Some questions about this code:
    >
    > template <typename T> class MyTemplate;
    > template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    > object);
    > template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    > object1, const MyTemplate <T> & object2);
    >
    > template <typename T>
    > class MyTemplate
    > {
    > public:
    > MyTemplate (const T & data = T()) : mData(data) {}
    > MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}
    >
    > MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
    > object.mData; return *this; }
    >
    > friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object);
    > MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
    > object.mData; return *this; }
    > friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
    > const MyTemplate <T> & object2);
    >
    > private:
    >
    > T mData;
    > };
    >
    > template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    > object) { return MyTemplate <T> (-object.mData); }
    > template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    > object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
    > result -= object2; return result; }
    >
    > int
    > main
    > {
    > MyTemplate <float> object1(1.0f);
    > MyTemplate <float> object2(-object1);
    > }
    >
    > a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
    > unexpected token errors, first, and then some "new definition" errors for
    > the friend operator-, saying me that it was previously defined as a member.


    It compiles just fine with gcc 3.3.3 (after adding parantheses after
    main), so I suppose that there's nothing wring with the code as such.

    > b) Nothing to do with the previous question, first constructor have a
    > default parameter "const T & data = T()". When I instantiate MyTemplate
    > <float> objects through this constructor, both in the stack and in the heap,
    > mData is initialized to 0.0f value. Is this standard, being always all
    > built-in types initialized to zero when their default constructor (exists?)
    > is called (inside a template, for example)? Is this a coincidence, favoured
    > by the involved memory contents at the construction time? Or is this
    > compiler-dependent, implemented specifically by (in my case) MS Visual C++
    > 7.x?


    I don't believe the standard says anything about implicitly initializing
    variables, so (without reading the standard) I'd say it's
    compiler-dependent.

    / martin
    Martin Magnusson, Nov 30, 2004
    #2
    1. Advertising

  3. Ruben Campos

    Ruben Campos Guest

    "Martin Magnusson" <> escribió en el mensaje
    news:1101811069.OMD19JDIzON1F445jEDYbw@teranews...
    > Ruben Campos wrote:
    >> Some questions about this code:
    >>
    >> template <typename T> class MyTemplate;
    >> template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    >> object);
    >> template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    >> object1, const MyTemplate <T> & object2);
    >>
    >> template <typename T>
    >> class MyTemplate
    >> {
    >> public:
    >> MyTemplate (const T & data = T()) : mData(data) {}
    >> MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}
    >>
    >> MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
    >> object.mData; return *this; }
    >>
    >> friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object);
    >> MyTemplate <T> & operator-= (const MyTemplate <T> & object) {
    >> mData -= object.mData; return *this; }
    >> friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
    >> const MyTemplate <T> & object2);
    >>
    >> private:
    >>
    >> T mData;
    >> };
    >>
    >> template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    >> object) { return MyTemplate <T> (-object.mData); }
    >> template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    >> object1, const MyTemplate <T> & object2) { MyTemplate <T>
    >> result(object1); result -= object2; return result; }
    >>
    >> int
    >> main
    >> {
    >> MyTemplate <float> object1(1.0f);
    >> MyTemplate <float> object2(-object1);
    >> }
    >>
    >> a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax
    >> and unexpected token errors, first, and then some "new definition" errors
    >> for the friend operator-, saying me that it was previously defined as a
    >> member.

    >
    > It compiles just fine with gcc 3.3.3 (after adding parantheses after
    > main), so I suppose that there's nothing wring with the code as such.


    Sorry, it's only a transcription error. It should appear as:

    int
    main (int argn, char ** argc)

    The errors I've described are related with the template, and its friend
    functions. They appear with MS Visual C++ 7.1.3088, even when enabling the
    Microsoft language extensions (which I don't want to keep enabled).

    >
    >> b) Nothing to do with the previous question, first constructor have a
    >> default parameter "const T & data = T()". When I instantiate MyTemplate
    >> <float> objects through this constructor, both in the stack and in the
    >> heap, mData is initialized to 0.0f value. Is this standard, being always
    >> all built-in types initialized to zero when their default constructor
    >> (exists?) is called (inside a template, for example)? Is this a
    >> coincidence, favoured by the involved memory contents at the construction
    >> time? Or is this compiler-dependent, implemented specifically by (in my
    >> case) MS Visual C++ 7.x?

    >
    > I don't believe the standard says anything about implicitly initializing
    > variables, so (without reading the standard) I'd say it's
    > compiler-dependent.
    >
    > / martin
    Ruben Campos, Nov 30, 2004
    #3
  4. Ruben Campos

    Ruben Campos Guest

    Sorry. I included the code corresponding to the first compilable variation
    code, that with unary operator- as a friend function. So tell me repeat my
    first message, now corrected. Sorry, Martin Magnusson, for this (all mine)
    mistake.

    Some questions about this code:

    template <typename T> class MyTemplate;
    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object1, const MyTemplate <T> & object2);

    template <typename T>
    class MyTemplate
    {
    public:
    MyTemplate (const T & data = T()) : mData(data) {}
    MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}

    MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
    object.mData; return *this; }

    MyTemplate <T> operator- (const MyTemplate <T> & object) { return
    MyTemplate <T> (-mData); }
    MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
    object.mData; return *this; }
    friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
    const MyTemplate <T> & object2);

    private:
    T mData;
    };

    template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
    object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
    result -= object2; return result; }

    int
    main (int argn, char ** argc)
    {
    MyTemplate <float> object1(1.0f);
    MyTemplate <float> object2(-object1);
    }

    a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
    unexpected token errors, first, and then some "new definition" errors for
    the binary friend operator-, saying me that it was previously defined as a
    member. In fact, unary operator- is defined as a member, and subsequently
    binary operator- is defined as a friend function. So, are they considered
    the same function by the compiler? This doesn't make sense for me, because
    they have different parameters.

    In order to deal with this, I've tried two alternatives: a) changing the
    template MyTemplate <T> class for a non-template one, while keeping the
    unary member and binary friend operator-, and b) keep MyTemplate <T> as a
    template class, while changing member unary operator- for a friend one. In
    both cases, these errors don't appear, and the code compiles (and works)
    fine. So I know it is a fact which concern templates only. Is possible to
    include a unary member operator- and a binary friend operator- in the same
    template class?

    NOTE: in a real case, I use to include all the implementations in a separate
    ..cpp file (which, in the case of template classes, is #included in the .h).
    For readability, and for short, I included here implementation of member
    functions directly inside template class declaration, but I kept the
    implementation of the friend function outside, in order to reproduce the
    error situation. I've tried this code, however, and it really returns me
    errors which I've mentioned.

    b) Nothing to do with the previous question, first constructor have a
    default parameter "const T & data = T()". When I instantiate MyTemplate
    <float> objects through this constructor, both in the stack and in the heap,
    mData is initialized to 0.0f value. Is this standard, being always all
    built-in types initialized to zero when their default constructor (exists?)
    is called (inside a template, for example)? Is this a coincidence, favoured
    by the involved memory contents at the construction time? Or is this
    compiler-dependent, implemented specifically by (in my case) MS Visual C++
    7.x?
    Ruben Campos, Nov 30, 2004
    #4
  5. Ruben Campos

    Dan Cernat Guest

    "Ruben Campos" <> wrote in message news:<cohg0f$jr5$>...
    > Some questions about this code:


    [snip]

    > int
    > main

    main ()
    > {
    > MyTemplate <float> object1(1.0f);
    > MyTemplate <float> object2(-object1);
    > }
    >


    With the fix for main compiles just fine with VC++ 7.1

    /dan
    Dan Cernat, Nov 30, 2004
    #5
  6. Ruben Campos

    Ruben Campos Guest

    Please, see my last (and corrected) message in this thread. Sorry for the
    mistake, and thank you for your time.

    "Dan Cernat" <> escribió en el mensaje
    news:...
    > "Ruben Campos" <> wrote in message
    > news:<cohg0f$jr5$>...
    >> Some questions about this code:

    >
    > [snip]
    >
    >> int
    >> main

    > main ()
    >> {
    >> MyTemplate <float> object1(1.0f);
    >> MyTemplate <float> object2(-object1);
    >> }
    >>

    >
    > With the fix for main compiles just fine with VC++ 7.1
    >
    > /dan
    Ruben Campos, Nov 30, 2004
    #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. Ashwin  N

    Associativity of unary operators

    Ashwin N, Sep 8, 2006, in forum: Java
    Replies:
    4
    Views:
    1,684
    Stefan Ram
    Sep 9, 2006
  2. dspfun

    Associativity of unary C Operators

    dspfun, Jan 1, 2007, in forum: C Programming
    Replies:
    28
    Views:
    866
    CBFalconer
    Jan 5, 2007
  3. SpOiLeR
    Replies:
    10
    Views:
    795
    SpOiLeR
    Oct 19, 2005
  4. JanW
    Replies:
    2
    Views:
    312
    Gennaro Prota
    Oct 3, 2008
  5. mathog

    historical question, C unary operators

    mathog, Mar 29, 2012, in forum: C Programming
    Replies:
    13
    Views:
    1,369
    Eric Sosman
    Mar 30, 2012
Loading...

Share This Page