error occurs if output operator is made a template

Discussion in 'C++' started by subramanian100in@yahoo.com, India, Jul 25, 2010.

  1. , India

    , India Guest

    Consider the foillowing program x.cpp:

    #include <cstdlib>
    #include <iostream>
    #include <string>

    using namespace std;

    template <typename T>
    class TemplateClass
    {
    public:
    explicit TemplateClass(const T& arg = T());
    ostream& print(ostream& os) const;

    private:
    T t;
    };

    template<typename T>
    inline TemplateClass<T>::TemplateClass(const T& arg) : t(arg)
    {
    }

    template <typename T>
    inline ostream& TemplateClass<T>::print(ostream& os) const
    {
    return os << "from TemplateClass<T>::print(): " << t;
    }

    template <typename T>
    inline ostream& operator<<(ostream& os, const T& obj)
    {
    return obj.print(os);
    }

    int main()
    {
    string str("Test string");
    TemplateClass<string> obj(str);

    cout << obj << endl;

    return EXIT_SUCCESS;
    }

    When I compile this program as
    g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

    I get the following errors:

    x.cpp: In member function `std::eek:stream&
    TemplateClass<T>::print(std::eek:stream&) const [with T = std::string]':
    x.cpp:32: instantiated from `std::eek:stream& operator<<(std::eek:stream&,
    const T&) [with T = TemplateClass<std::string>]'
    x.cpp:40: instantiated from here
    x.cpp:26: error: ambiguous overload for 'operator<<' in 'os << "from
    TemplateClass<T>::print(): "'
    x.cpp:31: note: std::eek:stream&
    operator<<(std::eek:stream&, const T&) [with T = char[33]]

    These errors occur because I have made the 'operator<<' a
    function template. Is it correct ?

    Is it possible to get rid of these compilation errors while keeping
    the 'operator<<' a function template ? If so kindly explain with
    program sample. If not possible, then we have to write

    inline ostream& operator<<(ostream& os,
    const SomeSpecificType& obj)
    where 'SomeSpecificType' is a explicit class name.
    Is this understanding of mine is correct ?

    Thanks
    V.Subramanian
     
    , India, Jul 25, 2010
    #1
    1. Advertising

  2. , India

    Ron AF Greve Guest

    Hi,

    It tries to find a function ostream.operator<<( TemplateClass .... )

    which doesn't exist.

    You have to define a friend template function:

    Like for instance this (replace with MChannel with ostream and KDTriangleT
    with your type and adjust template arguments and implementation
    accordingly.:

    template ......

    template <typename VerticeT, typename FloatT, typename IntT>
    friend MChannel& operator<<( MChannel& Channel, const KDTriangleT<VerticeT,
    FloatT, IntT>& Triangle );
    };

    template <typename VerticeT, typename FloatT, typename IntT>
    inline MChannel& operator<<( MChannel& Channel, const KDTriangleT<VerticeT,
    FloatT, IntT>& Triangle )
    {
    Channel << "-- Triangle" << endl;
    Channel << " " << Triangle.Vertices[ 0 ] << endl;
    Channel << " " << Triangle.Vertices[ 1 ] << endl;
    Channel << " " << Triangle.Vertices[ 2 ] << endl;
    return Channel;
    }

    <> wrote in message
    news:...
    | Consider the foillowing program x.cpp:
    |
    | #include <cstdlib>
    | #include <iostream>
    | #include <string>
    |
    | using namespace std;
    |
    | template <typename T>
    | class TemplateClass
    | {
    | public:
    | explicit TemplateClass(const T& arg = T());
    | ostream& print(ostream& os) const;
    |
    | private:
    | T t;
    | };
    |
    | template<typename T>
    | inline TemplateClass<T>::TemplateClass(const T& arg) : t(arg)
    | {
    | }
    |
    | template <typename T>
    | inline ostream& TemplateClass<T>::print(ostream& os) const
    | {
    | return os << "from TemplateClass<T>::print(): " << t;
    | }
    |
    | template <typename T>
    | inline ostream& operator<<(ostream& os, const T& obj)
    | {
    | return obj.print(os);
    | }
    |
    | int main()
    | {
    | string str("Test string");
    | TemplateClass<string> obj(str);
    |
    | cout << obj << endl;
    |
    | return EXIT_SUCCESS;
    | }
    |
    | When I compile this program as
    | g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
    |
    | I get the following errors:
    |
    | x.cpp: In member function `std::eek:stream&
    | TemplateClass<T>::print(std::eek:stream&) const [with T = std::string]':
    | x.cpp:32: instantiated from `std::eek:stream& operator<<(std::eek:stream&,
    | const T&) [with T = TemplateClass<std::string>]'
    | x.cpp:40: instantiated from here
    | x.cpp:26: error: ambiguous overload for 'operator<<' in 'os << "from
    | TemplateClass<T>::print(): "'
    | x.cpp:31: note: std::eek:stream&
    | operator<<(std::eek:stream&, const T&) [with T = char[33]]
    |
    | These errors occur because I have made the 'operator<<' a
    | function template. Is it correct ?
    |
    | Is it possible to get rid of these compilation errors while keeping
    | the 'operator<<' a function template ? If so kindly explain with
    | program sample. If not possible, then we have to write
    |
    | inline ostream& operator<<(ostream& os,
    | const SomeSpecificType& obj)
    | where 'SomeSpecificType' is a explicit class name.
    | Is this understanding of mine is correct ?
    |
    | Thanks
    | V.Subramanian
    |

    --
    Regards, Ron AF Greve

    http://informationsuperhighway.eu
     
    Ron AF Greve, Jul 25, 2010
    #2
    1. Advertising

  3. , India

    Bo Persson Guest

    wrote:
    > Consider the foillowing program x.cpp:
    >
    > #include <cstdlib>
    > #include <iostream>
    > #include <string>
    >
    > using namespace std;
    >
    > template <typename T>
    > class TemplateClass
    > {
    > public:
    > explicit TemplateClass(const T& arg = T());
    > ostream& print(ostream& os) const;
    >
    > private:
    > T t;
    > };
    >
    > template<typename T>
    > inline TemplateClass<T>::TemplateClass(const T& arg) : t(arg)
    > {
    > }
    >
    > template <typename T>
    > inline ostream& TemplateClass<T>::print(ostream& os) const
    > {
    > return os << "from TemplateClass<T>::print(): " << t;
    > }
    >
    > template <typename T>
    > inline ostream& operator<<(ostream& os, const T& obj)
    > {
    > return obj.print(os);
    > }


    This functions is WAY too general, as it matches any type, not just
    your type but also int or std::string.

    That's what the error message is about - in your print function the

    os << "from TemplateClass<T>::print(): "

    part matches both your operator<< and the one already defined in the
    standard library.


    Bo Persson
     
    Bo Persson, Jul 25, 2010
    #3
  4. , India

    James Kanze Guest

    On Jul 25, 3:52 pm, "Ron AF Greve" <me@localhost> wrote:

    > It tries to find a function ostream.operator<<( TemplateClass
    > .... )


    Why would it try to do that? His left hand operator is an
    std::eek:stream&, not a TemplateClass.

    > which doesn't exist.


    > You have to define a friend template function:


    Making operator<< a friend is one solution, but not the only
    one. His solution works quite well, if he declares the template
    correctly, so that it only matches his TemplateClass, and not
    everything in the world, e.g.:
    template<typename T>
    std::eek:stream& operator<<( std::eek:stream const& dest,
    TemplateClass<T> const& source);

    > <> wrote in message


    And you really shouldn't top post.

    --
    James Kanze
     
    James Kanze, Jul 25, 2010
    #4
  5. ", India" <> writes:

    > Consider the foillowing program x.cpp:
    >
    > #include <cstdlib>
    > #include <iostream>
    > #include <string>
    >
    > using namespace std;
    >
    > template <typename T>
    > class TemplateClass
    > {
    > public:
    > explicit TemplateClass(const T& arg = T());
    > ostream& print(ostream& os) const;
    >
    > private:
    > T t;
    > };
    >
    > template<typename T>
    > inline TemplateClass<T>::TemplateClass(const T& arg) : t(arg)
    > {
    > }
    >
    > template <typename T>
    > inline ostream& TemplateClass<T>::print(ostream& os) const
    > {
    > return os << "from TemplateClass<T>::print(): " << t;
    > }
    >
    > template <typename T>
    > inline ostream& operator<<(ostream& os, const T& obj)
    > {
    > return obj.print(os);
    > }
    >
    > int main()
    > {
    > string str("Test string");
    > TemplateClass<string> obj(str);
    >
    > cout << obj << endl;
    >
    > return EXIT_SUCCESS;
    > }
    >
    > When I compile this program as
    > g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
    >
    > I get the following errors:
    >
    > x.cpp: In member function `std::eek:stream&
    > TemplateClass<T>::print(std::eek:stream&) const [with T = std::string]':
    > x.cpp:32: instantiated from `std::eek:stream& operator<<(std::eek:stream&,
    > const T&) [with T = TemplateClass<std::string>]'
    > x.cpp:40: instantiated from here
    > x.cpp:26: error: ambiguous overload for 'operator<<' in 'os << "from
    > TemplateClass<T>::print(): "'
    > x.cpp:31: note: std::eek:stream&
    > operator<<(std::eek:stream&, const T&) [with T = char[33]]
    >
    > These errors occur because I have made the 'operator<<' a
    > function template. Is it correct ?
    >
    > Is it possible to get rid of these compilation errors while keeping
    > the 'operator<<' a function template ? If so kindly explain with
    > program sample. If not possible, then we have to write
    >
    > inline ostream& operator<<(ostream& os,
    > const SomeSpecificType& obj)
    > where 'SomeSpecificType' is a explicit class name.
    > Is this understanding of mine is correct ?



    You're missing the solution, which is somewhere in between these two.
    Write your op<< as:

    template<typename T>
    inline ostream& operator<<(ostream& os, const TemplateClass<T>& obj)
    { ^^^^^^^^^^^^^^^^
    return obj.print(os);
    }

    Regards

    Paul Bibbings
     
    Paul Bibbings, Jul 25, 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. Lloyd Sheen
    Replies:
    3
    Views:
    376
    Lloyd Sheen
    Mar 7, 2004
  2. =?Utf-8?B?UlVTU0VMTCBNQ0dJTk5JUw==?=

    Can you intercept the url request before a 404 error occurs?

    =?Utf-8?B?UlVTU0VMTCBNQ0dJTk5JUw==?=, Jul 14, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    700
    Scott Allen
    Jul 14, 2004
  3. Andy G

    Send email when error occurs

    Andy G, Mar 18, 2005, in forum: ASP .Net
    Replies:
    5
    Views:
    585
    Andy G
    Mar 18, 2005
  4. Randy
    Replies:
    23
    Views:
    855
  5. Geek
    Replies:
    3
    Views:
    159
Loading...

Share This Page