Re: Overload resolution compilation error

2007-07-30 Thread Rodolfo Schulz de Lima

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

2007-07-20 Thread Ling-hua Tseng
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

2007-07-20 Thread Dave Korn
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

2007-07-20 Thread Rodolfo Schulz de Lima

  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

2007-07-20 Thread Dave Korn
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

2007-07-20 Thread Rodolfo Schulz de Lima

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

2007-07-19 Thread Ling-hua Tseng
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

2007-07-19 Thread Rodolfo Lima
"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

2007-07-19 Thread Ling-hua Tseng
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

2007-07-19 Thread Rodolfo Lima
> 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

2007-07-19 Thread Ling-hua Tseng
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

2007-07-19 Thread Rodolfo Schulz de Lima

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

2007-07-19 Thread Ling-hua Tseng
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.