why overloading isn't happened?

Discussion in 'C++' started by 胡岳偉(Yueh-Wei Hu), May 21, 2004.

  1. Hi all,

    I have 2 questions about template function as friends in template
    classes. I don't know why, and hope someone could help me.

    ==============================================================
    Question 1:
    ==============================================================

    Compile the following codes, and run it.
    The program will print

    "T<a, b>"

    on the screen.

    However, I consider that "T<a, 3>" should be displayed.

    Why this program print "T<a, b>"?

    My building environment is:

    1) gcc-3.3
    2) linux kernel 2.6.6

    ==============================================================

    #include <iostream>

    template<int a, int b>
    class T;

    template<int a, int b>
    void func(T<a, b> const * const t)
    {
    t->c = 3;
    std::cerr << "T<a, b>" << std::endl;
    }

    template<int a, int b>
    class T
    {
    private:

    int c;

    friend void func<a, b>(T<a, b> const * const t);
    friend void func<a>(T<a, 3> const * const t);

    public:

    void ttt() const;
    };

    template<int a>
    void
    func(T<a, 3> const * const t)
    {
    t->c = 2;
    std::cerr << "T<a, 3>" << std::endl;
    }

    template<int a, int b>
    void
    T<a, b>::ttt() const
    {
    func(this);
    }

    int
    main()
    {
    T<2, 3> t;

    t.ttt();

    return 0;
    }

    =============================================================
    Question 2:
    =============================================================

    I add another function template:

    friend void func<b>(T<3, b> const * const t);

    and define it, too.

    However, when I compile this program, gcc shows the following error
    message:

    eee.cpp: In instantiation of `T<2, 3>':
    eee.cpp:50: instantiated from here
    eee.cpp:19: error: ambiguous template specialization `func<3>' for
    `void
    func(const T<3, 3>*)'

    What does the 'ambiguous template specialization' indicate?
    I can't figure it out.

    Thank you for your help.

    =============================================================

    #include <iostream>

    template<int a, int b>
    class T;

    template<int a, int b>
    void func(T<a, b> const * const t)
    {
    t->c = 3;
    std::cerr << "T<a, b>" << std::endl;
    }

    template<int a, int b>
    class T
    {
    private:

    friend void func<a, b>(T<a, b> const * const t);
    //friend void func<a>(T<a, 3> const * const t);
    friend void func<b>(T<3, b> const * const t); <-- add this line -->

    public:

    void ttt() const;
    };

    template<int a>
    void
    func(T<a, 3> const * const t)
    {
    t->c = 2;
    std::cerr << "T<a, 3>" << std::endl;
    }

    template<int b> <-- add definition -->
    void
    func(T<3, b> const * const t)
    {
    t->c = 1;
    std::cerr << "T<3, b>" << std::endl;
    }

    template<int a, int b>
    void
    T<a, b>::ttt() const
    {
    func(this);
    }

    int
    main()
    {
    T<2, 3> t;

    t.ttt();

    return 0;
    }

    ==============================================================
    胡岳偉(Yueh-Wei Hu), May 21, 2004
    #1
    1. Advertising

  2. Yueh-Wei Hu wrote:
    > I have 2 questions about template function as friends in template
    > classes. I don't know why, and hope someone could help me.
    >
    > ==============================================================
    > Question 1:
    > ==============================================================
    >
    > Compile the following codes, and run it.


    Your code refuses to compile. In function 'foo<a>' 't' is a pointer to
    const. Friendship has nothing to do with it. When I remove the attempt
    to change 't->c' in foo<a>, it compiles and runs and displays

    T<a, 3>

    > The program will print
    >
    > "T<a, b>"
    >
    > on the screen.
    >
    > However, I consider that "T<a, 3>" should be displayed.


    When the program is corrected, yes.

    >
    > Why this program print "T<a, b>"?


    Because you have a buggy compiler, probably...

    >
    > My building environment is:
    >
    > 1) gcc-3.3
    > 2) linux kernel 2.6.6


    Fall back on gcc-3.2

    >
    > ==============================================================
    >
    > #include <iostream>
    >
    > template<int a, int b>
    > class T;
    >
    > template<int a, int b>
    > void func(T<a, b> const * const t)
    > {
    > t->c = 3;


    '*t' is const here. Friendship doesn't change that. Comment it out.

    > std::cerr << "T<a, b>" << std::endl;
    > }
    >
    > template<int a, int b>
    > class T
    > {
    > private:
    >
    > int c;
    >
    > friend void func<a, b>(T<a, b> const * const t);
    > friend void func<a>(T<a, 3> const * const t);
    >
    > public:
    >
    > void ttt() const;
    > };
    >
    > template<int a>
    > void
    > func(T<a, 3> const * const t)
    > {
    > t->c = 2;


    Again, '*t' is a const object. Comment this out too.

    > std::cerr << "T<a, 3>" << std::endl;
    > }
    >
    > template<int a, int b>
    > void
    > T<a, b>::ttt() const
    > {
    > func(this);
    > }
    >
    > int
    > main()
    > {
    > T<2, 3> t;
    >
    > t.ttt();
    >
    > return 0;
    > }


    After commenting out the offending lines, the code compiles fine (as it
    should).

    >
    > =============================================================
    > Question 2:
    > =============================================================
    >
    > I add another function template:
    >
    > friend void func<b>(T<3, b> const * const t);
    >
    > and define it, too.
    >
    > However, when I compile this program, gcc shows the following error
    > message:
    >
    > eee.cpp: In instantiation of `T<2, 3>':
    > eee.cpp:50: instantiated from here
    > eee.cpp:19: error: ambiguous template specialization `func<3>' for
    > `void
    > func(const T<3, 3>*)'
    >
    > What does the 'ambiguous template specialization' indicate?
    > I can't figure it out.


    Neither can I. The code compiles file once the offending lines that
    attemp to change 't->c' are commented out and the resulting program outputs

    T<a, 3>

    > Thank you for your help.
    > [...]


    Victor
    Victor Bazarov, May 21, 2004
    #2
    1. Advertising

  3. Re: why overloading isn't happened? (using friend function template in class template)

    Victor Bazarov <> wrote in message news:<AGrrc.377$>...
    ==============================================================
    > > Question 1:
    > > ==============================================================


    > Your code refuses to compile. In function 'foo<a>' 't' is a pointer to
    > const. Friendship has nothing to do with it. When I remove the attempt
    > to change 't->c' in foo<a>, it compiles and runs and displays
    >
    > T<a, 3>
    >


    This is my fault, sorry.

    The 't->c' assignment is added by me after I copied and pasted the
    source codes to the news.

    The reason why I did this is to emphasize the need of 'friend'
    declarations.

    > Fall back on gcc-3.2


    I fall back to gcc-3.2, and I can _not_ compile it !

    The error message from gcc-3.2 is as following:

    ==============================================================

    eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
    2, int b =
    3]':
    eee.cpp:52: instantiated from here
    eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
    ambiguous
    eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
    int b =
    3]
    eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]
    eee.cpp:8: void func(const T<a, b>*) [with int a = 2,
    int b =
    3]
    eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]

    ==============================================================

    The source code is as following:

    ==============================================================

    #include <iostream>

    template<int a, int b>
    class T;

    template<int a, int b>
    void func(T<a, b> const * const t)
    {
    std::cerr << "T<a, b>" << std::endl;
    }

    template<int a, int b>
    class T
    {
    private:

    friend void func<a, b>(T<a, b> const * const t);
    friend void func<a>(T<a, 3> const * const t);

    public:

    void ttt() const;
    };

    template<int a>
    void
    func(T<a, 3> const * const t)
    {
    std::cerr << "T<a, 3>" << std::endl;
    }


    template<int a, int b>
    void
    T<a, b>::ttt() const
    {
    func(this);
    }

    int
    main()
    {
    T<2, 3> t;

    t.ttt();

    return 0;
    }

    ==============================================================

    However, when I use gcc-3.2, gcc-3.3, gcc-3.4 to compile my code, the
    result is strange.

    Here is my result:

    1) gcc-3.2: can _not_ compile, the error message is copied and pasted
    above.

    2) gcc-3.3: can compile, but the result is

    T<a, b>

    3) gcc-3.4: can compile, but the result is

    T<a, b>

    So....
    What behavior conforms to the C++ standard?
    And which version of gcc is correct?

    =============================================================
    > > Question 2:
    > > =============================================================


    >
    > Neither can I. The code compiles file once the offending lines that
    > attemp to change 't->c' are commented out and the resulting program outputs
    >
    > T<a, 3>
    >
    >
    > Victor


    I can _not_ compile the code using gcc-3.2, and the error message is
    like the one I posted above:

    ==============================================================

    eee.cpp: In instantiation of `T<2, 3>':
    eee.cpp:50: instantiated from here
    eee.cpp:19: ambiguous template specialization `func<3>' for `void
    func(const
    T<3, 3>*)'
    eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
    2, int b =
    3]':
    eee.cpp:52: instantiated from here
    eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
    ambiguous
    eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
    int b =
    3]
    eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]
    eee.cpp:8: void func(const T<a, b>*) [with int a = 2,
    int b =
    3]
    eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]

    ==============================================================

    The source code I use is as following:

    ==============================================================

    #include <iostream>

    template<int a, int b>
    class T;

    template<int a, int b>
    void func(T<a, b> const * const t)
    {
    std::cerr << "T<a, b>" << std::endl;
    }

    template<int a, int b>
    class T
    {
    private:

    friend void func<a, b>(T<a, b> const * const t);
    friend void func<a>(T<a, 3> const * const t);
    friend void func<b>(T<3, b> const * const t); <-- add this -->

    public:

    void ttt() const;
    };

    template<int a>
    void
    func(T<a, 3> const * const t)
    {
    std::cerr << "T<a, 3>" << std::endl;
    }

    template<int b> <-- add this definition -->
    void
    func(T<3, b> const * const t)
    {
    std::cerr << "T<3, b>" << std::endl;
    }

    template<int a, int b>
    void
    T<a, b>::ttt() const
    {
    func(this);
    }

    int
    main()
    {
    T<2, 3> t;

    t.ttt();

    return 0;
    }

    ==============================================================

    Again, the following is the result when I compile it using gcc-3.2,
    gcc-3.3 and gcc-3.4:

    1) gcc-3.2: can _not_ compile, the error message posted above.
    2) gcc-3.3: can _not_ compile, the error message just like the one
    posted for gcc-3.2.
    3) gcc-3.4: can compile, but the result is

    T<a, b>

    ==============================================================

    I can not figure it out why overload doesn't appear.
    Could somebody explain this?

    Thank you for you help.
    胡岳偉(Yueh-Wei Hu), May 22, 2004
    #3
  4. Re: why overloading isn't happened? (using friend function template in class template)

    Yueh-Wei Hu <> wrote...
    > Victor Bazarov <> wrote in message

    news:<AGrrc.377$>...
    > ==============================================================
    > > > Question 1:
    > > > ==============================================================

    >
    > > Your code refuses to compile. In function 'foo<a>' 't' is a pointer to
    > > const. Friendship has nothing to do with it. When I remove the attempt
    > > to change 't->c' in foo<a>, it compiles and runs and displays
    > >
    > > T<a, 3>
    > >

    >
    > This is my fault, sorry.
    >
    > The 't->c' assignment is added by me after I copied and pasted the
    > source codes to the news.
    >
    > The reason why I did this is to emphasize the need of 'friend'
    > declarations.
    >
    > > Fall back on gcc-3.2

    >
    > I fall back to gcc-3.2, and I can _not_ compile it !
    >
    > The error message from gcc-3.2 is as following:
    > [...]
    >
    > I can not figure it out why overload doesn't appear.
    > Could somebody explain this?


    You need to talk to people in a gnu newsgroup. Apparently gcc is
    still behind on the standard compliancy. The explanation is simple:
    the compiler is not up to par. The solution is simpler: use another
    [better] compiler. If you can't, you're screwed until they manage
    to fix it.

    Victor
    Victor Bazarov, May 22, 2004
    #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. Replies:
    8
    Views:
    896
    John C. Bollinger
    Mar 4, 2005
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    880
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,844
    Smokey Grindel
    Dec 2, 2006
  4. PerlFAQ Server
    Replies:
    0
    Views:
    588
    PerlFAQ Server
    Feb 11, 2011
  5. PerlFAQ Server
    Replies:
    0
    Views:
    584
    PerlFAQ Server
    Mar 9, 2011
Loading...

Share This Page