operator<< overload for inner enum of a template

Discussion in 'C++' started by Doctor Smith, Apr 10, 2008.

  1. Doctor Smith

    Doctor Smith Guest

    Hello!

    I would like to have an output streaming operator for an enum that is
    inside a templated class, but I just can't seem to make it work! I
    suspect that I have a template ambiguity issue, but I haven't pinned
    down what change will make the code work.

    The following example illustrates the problem. I would like the
    program to print 'C', but it prints '2'.

    #include <iostream>

    template <typename AX_FLOAT>
    class M
    {
    public:
    enum T
    {
    A,
    B,
    C
    };
    };

    template <typename AX_FLOAT>
    std::eek:stream& operator<<(std::eek:stream& os, typename M<AX_FLOAT>::T t)
    {
    switch (t)
    {
    case M<AX_FLOAT>::A: os << 'A'; break;
    case M<AX_FLOAT>::B: os << 'B'; break;
    case M<AX_FLOAT>::C: os << 'C'; break;
    }

    return os;
    }

    int main()
    {
    M<float>::T t = M<float>::C;

    std::cout << "t = " << t << std::endl;
    }

    Any insights on how to make this work, or why it will never work, is
    muchly appreciated.
    Doctor Smith, Apr 10, 2008
    #1
    1. Advertising

  2. Doctor Smith

    Ian Collins Guest

    Doctor Smith wrote:
    > Hello!
    >
    > I would like to have an output streaming operator for an enum that is
    > inside a templated class, but I just can't seem to make it work! I
    > suspect that I have a template ambiguity issue, but I haven't pinned
    > down what change will make the code work.
    >
    > The following example illustrates the problem. I would like the
    > program to print 'C', but it prints '2'.
    >

    Try:

    template <typename AX_FLOAT>
    class M
    {
    public:
    enum T
    {
    A,
    B,
    C
    };

    friend std::eek:stream& operator<<(std::eek:stream& os, T t)
    {
    switch (t)
    {
    case M<AX_FLOAT>::A: os << 'A'; break;
    case M<AX_FLOAT>::B: os << 'B'; break;
    case M<AX_FLOAT>::C: os << 'C'; break;
    }

    return os;
    }
    };

    --
    Ian Collins.
    Ian Collins, Apr 10, 2008
    #2
    1. Advertising

  3. Doctor Smith

    Doctor Smith Guest

    Thanks! That little change fixed the problem neatly in my test
    program. Presumably it will work equally well in our project code.

    Though, it would be interesting to get the technical explanation as to
    why the first works and the second doesn't.

    On Apr 9, 7:35 pm, Ian Collins <> wrote:
    > Doctor Smith wrote:
    > > Hello!

    >
    > > I would like to have an output streaming operator for an enum that is
    > > inside a templated class, but I just can't seem to make it work!  I
    > > suspect that I have a template ambiguity issue, but I haven't pinned
    > > down what change will make the code work.

    >
    > > The following example illustrates the problem.  I would like the
    > > program to print 'C', but it prints '2'.

    >
    > Try:
    >
    > template <typename AX_FLOAT>
    > class M
    > {
    > public:
    >   enum T
    >     {
    >       A,
    >       B,
    >       C
    >     };
    >
    >   friend std::eek:stream& operator<<(std::eek:stream& os, T t)
    >   {
    >     switch (t)
    >     {
    >       case M<AX_FLOAT>::A: os << 'A'; break;
    >       case M<AX_FLOAT>::B: os << 'B'; break;
    >       case M<AX_FLOAT>::C: os << 'C'; break;
    >     }
    >
    >     return os;
    >   }
    >
    > };
    >
    > --
    > Ian Collins.
    Doctor Smith, Apr 10, 2008
    #3
  4. Doctor Smith

    Jerry Coffin Guest

    In article <9476484e-a0cf-4aef-b22a-
    >, says...
    > Hello!
    >
    > I would like to have an output streaming operator for an enum that is
    > inside a templated class, but I just can't seem to make it work! I
    > suspect that I have a template ambiguity issue, but I haven't pinned
    > down what change will make the code work.
    >
    > The following example illustrates the problem. I would like the
    > program to print 'C', but it prints '2'.


    One possibility would be like this:

    #include <iostream>

    template <typename F>
    struct M {
    enum Ts {A, B, C};

    class T {
    typename M::Ts t;
    public:
    T(typename M::Ts val) : t(val) {}

    friend std::eek:stream &operator<<(
    std::eek:stream &os,
    typename M<F>::T const &m)
    {
    static char const names[] = "ABC";
    return os << names[m.t];
    }
    };
    };

    int main()
    {
    M<float>::T t = M<float>::C;

    std::cout << "t = " << t << std::endl;
    }

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Apr 13, 2008
    #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. Piotre Ugrumov
    Replies:
    3
    Views:
    368
    Nick Hounsome
    Jan 25, 2004
  2. Atlas
    Replies:
    13
    Views:
    495
    Atlas
    Oct 20, 2005
  3. Fei Liu
    Replies:
    5
    Views:
    344
    Maxim Yegorushkin
    Feb 25, 2006
  4. fungus
    Replies:
    11
    Views:
    575
    fungus
    Jan 6, 2007
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    248
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page