 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Maxim Yegorushkin Guest
|
Posted: Sun Nov 28, 2004 6:09 pm Post subject: Strange overload resolution error |
|
|
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
|
Posted: Sun Nov 28, 2004 11:56 pm Post subject: Re: Strange overload resolution error |
|
|
"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
|
Posted: Sun Nov 28, 2004 11:57 pm Post subject: Re: Strange overload resolution error |
|
|
"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
|
Posted: Mon Nov 29, 2004 10:56 am Post subject: Re: Strange overload resolution error |
|
|
"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
|
Posted: Mon Nov 29, 2004 9:46 pm Post subject: Re: Strange overload resolution error |
|
|
"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
|
Posted: Tue Nov 30, 2004 11:07 am Post subject: Re: Strange overload resolution error |
|
|
"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 |
|
 |
|
|
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
|
|