C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Strange overload resolution error

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Maxim Yegorushkin
Guest





PostPosted: Sun Nov 28, 2004 6:09 pm    Post subject: Strange overload resolution error Reply with quote



I can't understand why in the following code the call foo(a, a) is ok,
while bar<int>(a, a) produces an error with Comeau online, Intel C++ 8,
gcc 3.2 but compiles fine with MSVC 7.1. It seems to me that the code
contains no ambiguity and the call bar<int>(a, a) should be resolved to
the second bar overload. Is there something I'm missing?

template<int n> struct int_ {};

template<int n, int m> void foo(int_<n>, int_<m>) {}
template<int n> void foo(int_<n>, int_<n>) {}

template<class T, int n, int m> void bar(int_<n>, int_<m>) {}
template<class T, int n> void bar(int_<n>, int_<n>) {}

int main()
{
int_<0> a;
int_<1> b;
foo(a, b); // ok
foo(a, a); // ok
bar<int>(a, b); // ok
bar<int>(a, a); // error
}

Comeau and Intel C++ 8:
error: more than one instance of overloaded function "bar" matches the
argument list:
function template "bar<T,n,m>(int_<m>, int_<m>)"
function template "bar<T,n>(int_<m>, int_<m>)"
argument types are: (int_<0>, int_<0>)
bar<int>(a, a);
^

gcc 3.2 (MinGW):
call of overloaded `bar(int_<0>&, int_<0>&)' is ambiguous candidates are:
void bar(int_<m>, int_<m>) [with T = int, int n = 0, int m = 0]
void bar(int_<m>, int_<m>) [with T = int, int n = 0]

MSVC 7.1 compiles the code fine.

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Terje Slettebų
Guest





PostPosted: Sun Nov 28, 2004 11:56 pm    Post subject: Re: Strange overload resolution error Reply with quote



"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote

Quote:
I can't understand why in the following code the call foo(a, a) is ok,
while bar<int>(a, a) produces an error with Comeau online, Intel C++ 8,
gcc 3.2 but compiles fine with MSVC 7.1. It seems to me that the code
contains no ambiguity and the call bar<int>(a, a) should be resolved to
the second bar overload. Is there something I'm missing?

This is a "common" stumbling block in C++ involving explicit specification
of template arguments in the presence of overloaded functions, and there's a
few DRs out for it (see
[url]http://www2.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214)[/url].

Quote:
template<int n> struct int_ {};

template<int n, int m> void foo(int_<n>, int_<m>) {}
template<int n> void foo(int_<n>, int_<n>) {}

template<class T, int n, int m> void bar(int_<n>, int_<m>) {}
template<class T, int n> void bar(int_<n>, int_<n>) {}

int main()
{
int_<0> a;
int_<1> b;
foo(a, b); // ok
foo(a, a); // ok
bar<int>(a, b); // ok
bar<int>(a, a); // error

As it says in th DR, neither of the function parameter lists of bar() allows
T to be deduced, so both deductions fail, and the call is ambiguous.

A solution to this has been incorporated into the working paper (October
2003), which would make bar<int>(a, a) call the last bar() definition, as
expected:

"In most cases, all template parameters must have values in order for
deduction to succeed, but for partial ordering purposes a template parameter
may remain without a value provided it is not used in the types being used
for partial ordering. [Note: A template parameter used in a non-deduced
context is considered used.]

[Example:

template <class T> T f(int); // #1
template <class T, class U> T f(U); // #2
void g() {
f<int>(1); // Calls #1
}

--end example]"

Quote:
}

Comeau and Intel C++ 8:
error: more than one instance of overloaded function "bar" matches the
argument list:
function template "bar<T,n,m>(int_<m>, int_<m>)"
function template "bar<T,n>(int_<m>, int_<m>)"
argument types are: (int_<0>, int_<0>)
bar<int>(a, a);
^

gcc 3.2 (MinGW):
call of overloaded `bar(int_<0>&, int_<0>&)' is ambiguous candidates are:
void bar(int_<m>, int_<m>) [with T = int, int n = 0, int m = 0]
void bar(int_<m>, int_<m>) [with T = int, int n = 0]

MSVC 7.1 compiles the code fine.

Maybe it does so due to the above DR...

Regards,

Terje



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Sun Nov 28, 2004 11:57 pm    Post subject: Re: Strange overload resolution error Reply with quote




"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opsh6fsjcgti5cme (AT) wkcg6rirwp (DOT) ..
Quote:
I can't understand why in the following code the call foo(a, a) is ok,
while bar<int>(a, a) produces an error with Comeau online, Intel C++ 8,
gcc 3.2 but compiles fine with MSVC 7.1. It seems to me that the code
contains no ambiguity and the call bar<int>(a, a) should be resolved to
the second bar overload. Is there something I'm missing?

template<int n> struct int_ {};

template<int n, int m> void foo(int_<n>, int_<m>) {}
template<int n> void foo(int_<n>, int_<n>) {}

template<class T, int n, int m> void bar(int_<n>, int_<m>) {}
template<class T, int n> void bar(int_<n>, int_<n>) {}

int main()
{
int_<0> a;
int_<1> b;
foo(a, b); // ok
foo(a, a); // ok
bar<int>(a, b); // ok
bar<int>(a, a); // error
}


I'd say it's 14.5.5.2/4 where it says that argument deduction is performed
against the other function templates. Since there is no wording that this
process includes an explicit template argument list (how could it; how
should the compiler know which template argument of function template 1
should correspond to which template argument needing explicit listing in
function template 2), the deduction fails and no one is more specialized
than the other.


Thomas



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tokyo Tomy
Guest





PostPosted: Mon Nov 29, 2004 10:56 am    Post subject: Re: Strange overload resolution error Reply with quote

"Thomas Mang" <nospam (AT) nospam (DOT) invalid> wrote

Quote:
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opsh6fsjcgti5cme (AT) wkcg6rirwp (DOT) ..
I can't understand why in the following code the call foo(a, a) is ok,
while bar<int>(a, a) produces an error with Comeau online, Intel C++ 8,
gcc 3.2 but compiles fine with MSVC 7.1. It seems to me that the code
contains no ambiguity and the call bar<int>(a, a) should be resolved to
the second bar overload. Is there something I'm missing?

template<int n> struct int_ {};

template<int n, int m> void foo(int_<n>, int_<m>) {}
template<int n> void foo(int_<n>, int_<n>) {}

template<class T, int n, int m> void bar(int_<n>, int_<m>) {}
template<class T, int n> void bar(int_<n>, int_<n>) {}

int main()
{
int_<0> a;
int_<1> b;
foo(a, b); // ok
foo(a, a); // ok
bar<int>(a, b); // ok
bar<int>(a, a); // error
}


I'd say it's 14.5.5.2/4 where it says that argument deduction is performed
against the other function templates. Since there is no wording that this
process includes an explicit template argument list (how could it; how
should the compiler know which template argument of function template 1
should correspond to which template argument needing explicit listing in
function template 2), the deduction fails and no one is more specialized
than the other.


You are right in the fact there is no wording that this process

includes an explicit template argument list at the 14.5.5.2/4. However
I don't understand the reason you gave:
Quote:
how could it; how should the compiler know which template argument of function
template 1 should correspond to which template argument needing explicit listing in
function template 2.

I think the int in bar<int>(a, a) correspond to the top template
argument, class T, in both the bar functions, and there is no
ambiguity in the correspondence between template parameters in the
both the functions.

If you change
template<class T, int n> void bar(int_<n>, int_<n>) to
template<int n, class T> void bar(int_<n>, int_<n>),
bar<int>(a, a) has not ambiguity to match with bar<T, n, m>.

Surely I have some misunderstandings. Would you kindly explain
further? Thank you for your time.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Mon Nov 29, 2004 9:46 pm    Post subject: Re: Strange overload resolution error Reply with quote


"Tokyo Tomy" <hosoda (AT) jtec (DOT) or.jp> schrieb im Newsbeitrag
news:49c1da0b.0411282309.f4759e1 (AT) posting (DOT) google.com...
Quote:
"Thomas Mang" <nospam (AT) nospam (DOT) invalid> wrote

"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opsh6fsjcgti5cme (AT) wkcg6rirwp (DOT) ..
I can't understand why in the following code the call foo(a, a) is
ok,
while bar<int>(a, a) produces an error with Comeau online, Intel C++
8,
gcc 3.2 but compiles fine with MSVC 7.1. It seems to me that the code
contains no ambiguity and the call bar<int>(a, a) should be resolved
to
the second bar overload. Is there something I'm missing?

template<int n> struct int_ {};

template<int n, int m> void foo(int_<n>, int_<m>) {}
template<int n> void foo(int_<n>, int_<n>) {}

template<class T, int n, int m> void bar(int_<n>, int_<m>) {}
template<class T, int n> void bar(int_<n>, int_<n>) {}

int main()
{
int_<0> a;
int_<1> b;
foo(a, b); // ok
foo(a, a); // ok
bar<int>(a, b); // ok
bar<int>(a, a); // error
}


I'd say it's 14.5.5.2/4 where it says that argument deduction is
performed
against the other function templates. Since there is no wording that
this
process includes an explicit template argument list (how could it; how
should the compiler know which template argument of function template 1
should correspond to which template argument needing explicit listing
in
function template 2), the deduction fails and no one is more
specialized
than the other.


You are right in the fact there is no wording that this process
includes an explicit template argument list at the 14.5.5.2/4. However
I don't understand the reason you gave:
how could it; how should the compiler know which template argument of
function
template 1 should correspond to which template argument needing
explicit listing in
function template 2.

I think the int in bar<int>(a, a) correspond to the top template
argument, class T, in both the bar functions, and there is no
ambiguity in the correspondence between template parameters in the
both the functions.


Well, my reasoning refered to the current wording of the standard. By
reading the DR (thanks to the link provided by Terje), one can find out the
proposed fixes to circumvent this. What you have written seems to be the
intended behaviour, but obviously it isn't the way the current Standard
describes the process, because cross - type deduction fails and the function
templates cannot be ordered.

Quote:

If you change
template<class T, int n> void bar(int_<n>, int_<n>) to
template<int n, class T> void bar(int_<n>, int_<n>),
bar<int>(a, a) has not ambiguity to match with bar<T, n, m>.

Surely I have some misunderstandings. Would you kindly explain
further? Thank you for your time.


Here, the second bar will not be instantiated, since type deduction for T
fails (14.8.2.4/3; bottom 2 sentences) So it's not added to the list of
candidate functions (see14.8.3/1), and thus does not play any role in
overload resolution. Overload resolution here picks unambiguously the only
candidate function, namely the instantiation of the first function template.


Thomas



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Tue Nov 30, 2004 11:07 am    Post subject: Re: Strange overload resolution error Reply with quote


"Thomas Mang" <nospam (AT) pop (DOT) ucsd.edu> schrieb im Newsbeitrag
news:41ab3c1a$0$8024$3b214f66 (AT) usenet (DOT) univie.ac.at...
Quote:

If you change
template<class T, int n> void bar(int_<n>, int_<n>) to
template<int n, class T> void bar(int_<n>, int_<n>),
bar<int>(a, a) has not ambiguity to match with bar<T, n, m>.

Surely I have some misunderstandings. Would you kindly explain
further? Thank you for your time.


Here, the second bar will not be instantiated, since type deduction for T
fails (14.8.2.4/3; bottom 2 sentences)


Sorry, I looked at the wrong function template.
Actually, it's already 14.8.2/2 that kicks in, because the template argument
isn't compatible with the template parameter list. Because of this, type
deduction already fails, T is not even involved any more.

The remaining steps are identical to my prior post.


Thomas



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.