Re: Overload resolution compilation error
Dave Korn escreveu: Thanks, and do drop a note back with a summary of what you find out over there when you're done; if there's definitely a bug in gcc's understanding of the resolution rules, obviously we'd like to open a PR and get it fixed. I think we have finally a consensus at http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/52087a72bdc5de5a Since the template parameter of the template function cannot be deduced, the only valid function for taking its address is the non-template one, so g++ should accept the code without error nor ambiguity. During this week I've come along with another possibly related error: template void foo(A0, A1) {} void bar() { &foo; } g++ signals an error, saying: teste.cpp: In function ‘void bar()’: teste.cpp:4: error: statement cannot resolve address of overloaded function I'm trying to get the address of a correctly specialized template function, but g++ cannot resolve it. And there's no overload situation there, just void foo(int, char) is being involved. I've not tested it with other compilers, but this bug is less subtle then the first one.
Re: Overload resolution compilation error
Rodolfo Schulz de Lima wrote > Ling-hua Tseng escreveu: > > Obviously, {1, 2, 4, 5, 6, 7} are not matched. > > Maybe you think that the item 3 is matched. > > Unfortunately, it stands for the non-template functions. > > Are you sure that it doesn't include template functions? Because I think > it makes sense to consider them too (as Visual Studio does). The point > is that non template functions arguments have higher priority than > template functions (as specified in paragraph 4), and IMO there's no > reason to differentiate between template and non-template functions' > argument target, making the latter work and the former not. Even if the they are accepted, we still have a problem. The target type is `F', and it cannot be deduced by template argument deduction mechanism since this mechanism need to know the type of `&print' for deducing. Nevertheless, the overload resoluion mechanism need to know what `F' is. Of course, the C++ standard didn't allow this infinite loop. The template argument deduction should be done first (maybe succeeded or failed). It's described in paragraph 2 of section 13.4 and section 14.8.8.2. The template argument deduction is failed in GCC, since I cannot find the following context in .cxx.003t.original after removing the two lines `call(&print<5>);' and `call(&print<7,6>);' from your original example: == ;; Function void call(F) [with F = void (*)()] (_Z4callIPFvvEEvT_) ;; enabled by -tree-original <>> >>; == Since the target type cannot be deduced by template argument deduction mechanism, the overload resolution mechanism will not able to select any function names. It's why I said the overload set is empty. However, I have tested your example by Comeau C++ compiler in strict C++03 mode. It's passed to compile without any problems, so I guess that perhaps you're right. I'll stop discussing the topic after this reply since it will be moved to comp.std.c++ after moderator approving it. I hope that we will able to get a good answer there.
RE: Overload resolution compilation error
On 20 July 2007 16:31, Rodolfo Schulz de Lima wrote: >> Guys, why don't you take this to comp.std.c++ to get an authoritative >> answer? That's where you'll find the greatest concentration of people who >> really know what the standard /actually means/ by what it says... > > Alright, thread moved to comp.lang.c++.moderated, subject "Overload > resolution with template and non-template functions", and it's waiting > for moderator approval. Thanks, and do drop a note back with a summary of what you find out over there when you're done; if there's definitely a bug in gcc's understanding of the resolution rules, obviously we'd like to open a PR and get it fixed. (It's more likely, however, that the behaviour you see with VS is some kind of non-conformance on their part; the MSVC compiler is IIRC notably less rigorous about implementing and enforcing some of the more complex restrictions in the standard.) cheers, DaveK -- Can't think of a witty .sigline today
Re: Overload resolution compilation error
Guys, why don't you take this to comp.std.c++ to get an authoritative answer? That's where you'll find the greatest concentration of people who really know what the standard /actually means/ by what it says... Alright, thread moved to comp.lang.c++.moderated, subject "Overload resolution with template and non-template functions", and it's waiting for moderator approval. Regards, Rodolfo Lima.
RE: Overload resolution compilation error
On 20 July 2007 14:57, Rodolfo Schulz de Lima wrote: > Ling-hua Tseng escreveu: >> Obviously, {1, 2, 4, 5, 6, 7} are not matched. >> Maybe you think that the item 3 is matched. >> Unfortunately, it stands for the non-template functions. > > Are you sure that it doesn't include template functions? Guys, why don't you take this to comp.std.c++ to get an authoritative answer? That's where you'll find the greatest concentration of people who really know what the standard /actually means/ by what it says... cheers, DaveK -- Can't think of a witty .sigline today
Re: Overload resolution compilation error
Ling-hua Tseng escreveu: Obviously, {1, 2, 4, 5, 6, 7} are not matched. Maybe you think that the item 3 is matched. Unfortunately, it stands for the non-template functions. Are you sure that it doesn't include template functions? Because I think it makes sense to consider them too (as Visual Studio does). The point is that non template functions arguments have higher priority than template functions (as specified in paragraph 4), and IMO there's no reason to differentiate between template and non-template functions' argument target, making the latter work and the former not. Regards, Rodolfo Lima.
Re: Overload resolution compilation error
On Thu, 19 Jul 2007 21:19:09 -0300, Rodolfo Lima wrote > In my first example, the target type is the type of the address > expression, It cannot be treated as the target in paragraph 1 of section 13.4 (ISO/IEC 14882:2003). Again, here is the list of possible targets: 1. an object or reference being initialized (8.5, 8.5.3), 2. the left side of an assignment (5.17), 3. a parameter of a function (5.2.2), 4. a parameter of a user-defined operator (13.5), 5. the return value of a function, operator function, or conversion (6.6.3), 6. an explicit type conversion (5.2.3, 5.2.9, 5.4), or 7. a non-type template-parameter (14.3.2). Obviously, {1, 2, 4, 5, 6, 7} are not matched. Maybe you think that the item 3 is matched. Unfortunately, it stands for the non-template functions. BTW, here are two important sentences after the 7 items: "The overloaded function name can be preceded by the & operator. An overloaded function name shall not be used without arguments in contexts other than those listed." Here is you original example code: == #include using namespace std; void print() { cout << "null" << endl; } template void print() { cout << i << endl; } template void print() { cout << i << ' ' << j << endl; } template void call(F f) { f(); } int main() { // proper way (according to g++) to call non-templated print // call(static_cast(&print)); call(&print); call(&print<5>); call(&print<7,6>); return 0; } == If you want to match the item 3, you have to replace the definition of call<> () to a non-template function: == void call(void (*f)()) { f(); } == And then it can be passed by g++. The 2nd line of main() which you marked is matched by item 6. Hence it can also compiled by g++. Again, the set of overloaded function has never contain anything in your original example. It's because you don't have any targets which are matched to any items of list in paragraph 1 of section 13.4. Maybe you think that it contained the non-template one at begining. No, it's also not in the set.
Re: Overload resolution compilation error
"Ling-hua Tseng" <[EMAIL PROTECTED]> escreveu na mensagem > What is the `target' in your program? > The answer is NOTHING. > So the set of overloaded functions is empty at beginning. In my first example, the target type is the type of the address expression, i.e., the type of the source. I'll repeat it here: template void bar(F f) {} template void foo(T v) {} void foo(int v) {} ... bar(&foo); According to the paragraph 2 of section 13.4, (and against of what I've said in my previous post), if there's a template function involved, the compiler tries to deduct the template arguments from the target type. If it succeeds, this specialization is added to the overload set. In my example, the compiler cannot deduct the template argument, so the template function doesn't get added to the overload set. Only the non-template function is added. Being the only function in the set, there's no ambiguity and the address of "void foo()" should be passed to "bar". Best regards, Rodolfo Lima.
Re: Overload resolution compilation error
On Thu, 19 Jul 2007 19:25:38 -0300, Rodolfo Lima wrote > If I understand this correctly, when we have the following declarations: > > template void foo() {} > void foo() {} > > The overload set for "&foo" at first contains all "void foo()" > and "void foo()". Then, because of the presence of the latter, the > former should be eliminated. In the end, only "void foo()" remains, > and we have no ambiguity. You forgot the hypothesis in the paragraph 1: "The function selected is the one whose type matches the target type required in the context. The target can be an object or reference being initialized (8.5, 8.5.3), the left side of an assignment (5.17), a parameter of a function (5.2.2), a parameter of a user-defined operator (13.5), the return value of a function, operator function, or conversion (6.6.3), an explicit type conversion (5.2.3, 5.2.9, 5.4), or a non-type template-parameter (14.3.2)." What is the `target' in your program? The answer is NOTHING. So the set of overloaded functions is empty at beginning. The following case can compile by g++: void (*fptr)() = &print; It's because it has the `target'. Your deduction can apply to this case, but it cannot apply to your example code.
Re: Overload resolution compilation error
> The function template `std::make_pair<>()' is an example. > You can directly call it without <>. > Since &print is not a call expression, C++ compilers cannot determine it > by > function arguments. You're right, I forgot that rather trivial example. But what I'm trying to achieve is the correct resolution when we don't have the function's parameters, as when we get the address of the function. Right now I have the c++ standard here, and in section 13.1 (over.over, or "Address of overloaded function"), the paragraph 4 says: "If more than one function is selected, any function template specializations in the set are eliminated if the set also contains a non-template function, and any given function template specialization F1 is eliminated if the set contains a second function template specialization whose function template is more specialized than the function template of F1 according to the partial ordering rules of 14.5.5.2. After such eliminations, if any, there shall remain exactly one selected function." If I understand this correctly, when we have the following declarations: template void foo() {} void foo() {} The overload set for "&foo" at first contains all "void foo()" and "void foo()". Then, because of the presence of the latter, the former should be eliminated. In the end, only "void foo()" remains, and we have no ambiguity. > This problem can be also reduced to this one: > == > void foo() { } > void foo(int) { } > > int main() > { >&foo; > } > == This is different because there's no function template involved. Regards, Rodolfo Lima.
Re: Overload resolution compilation error
On Thu, 19 Jul 2007 14:45:31 -0300, Rodolfo Schulz de Lima wrote > &print is not a call expression the same way &print<5> isn't, but > the latter is resolved correctly. It's because you have specified it explicitly. > I cannot see how a template function can be instantiated without <>, > since its instantiation needs the template parameters. That's why I > think that the compiler shouldn't even consider this situation in > overload resolution. With this said, in your exemple the only > overload for '&foo' should be 'void foo()'. The function template `std::make_pair<>()' is an example. You can directly call it without <>. Since &print is not a call expression, C++ compilers cannot determine it by function arguments. This problem can be also reduced to this one: == void foo() { } void foo(int) { } int main() { &foo; } == It's the same problem. The instantiations of a function template can co-exist with non-template function, and they're treated as overloaded functions in C++ compilers. In fact, the overload resolution mechanism is never performed here since it's not a call expression. You can only speicify it explicitly.
Re: Overload resolution compilation error
Ling-hua Tseng escreveu: Since the sub-expression `&print' is not a call expression, the overload resolution mechanism will not select the non-template version first. &print is not a call expression the same way &print<5> isn't, but the latter is resolved correctly. And the function templates can be instantiated without <>, so the C++ compiler is confused. I cannot see how a template function can be instantiated without <>, since its instantiation needs the template parameters. That's why I think that the compiler shouldn't even consider this situation in overload resolution. With this said, in your exemple the only overload for '&foo' should be 'void foo()'. == void foo() { } template void foo() { } int main() { &foo; } == It can help you to understand what's happend. Yes, thank you, your example is much more concise. Thanks, Rodolfo Lima.
Re: Overload resolution compilation error
On Thu, 19 Jul 2007 12:59:09 -0300, Rodolfo Schulz de Lima wrote > Hi, the code below doesn't compile with gcc-4.2, with the following error: > > test.cpp: In function int main(): > test.cpp:19: error: no matching function for call to > call() > > It compiles and runs fine with Visual Studio 2005. I think the > compiler should see that if I'm calling the non-templated 'print' > function and there's no other non-templated 'print' overload, it > should use 'void print()', with no ambiguity. > Since the sub-expression `&print' is not a call expression, the overload resolution mechanism will not select the non-template version first. And the function templates can be instantiated without <>, so the C++ compiler is confused. This problem can be reduced to: == void foo() { } template void foo() { } int main() { &foo; } == It can help you to understand what's happend.