 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
David Brownell Guest
|
Posted: Sun Dec 28, 2003 10:10 am Post subject: Templates and Functions |
|
|
Given the following code, why does the compiler always choose to call
the first version of Foo and how would I convince it to call the
second version when appropriate?
Thanks in advance for your help,
David
BTW, I am using VS.Net 7.1
#include <vector>
#include <iostream>
using std::cout;
template <typename Type>
void Foo(const Type &t)
{
cout << "Foo(const Type &)n";
}
template
void Foo(typename Container::iterator &t)
{
cout << "Foo(Container::iterator &)n";
}
int main(void)
{
std::vector
char c;
Foo(c);
Foo(v.begin());
return(0);
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sun Dec 28, 2003 3:53 pm Post subject: Re: Templates and Functions |
|
|
David Brownell wrote:
| Quote: | Given the following code, why does the compiler always choose to call
the first version of Foo and how would I convince it to call the
second version when appropriate?
template <typename Type
void Foo(const Type &t)
{
cout << "Foo(const Type &)n";
}
template
void Foo(typename Container::iterator &t)
{
cout << "Foo(Container::iterator &)n";
}
std::vector
char c;
Foo(c);
Foo(v.begin());
|
There is a flaw in your logic. Assume this code:
struct struct1
{
typedef int* iterator;
};
struct struct2
{
typedef int* iterator;
};
int* p;
Foo(f);
Which should the call to Foo call? Foo<int*>(), Foo<struct1>(),
Foo<struct2>() would all match but the first is already a good match, so
the compiler chooses that one.
If that was not intended, you might explicitly tell the compiler that you
want 'Foo<std::vector(v.begin());'.
Uli
[ 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 Dec 28, 2003 5:15 pm Post subject: Re: Templates and Functions |
|
|
David Brownell schrieb:
| Quote: | Given the following code, why does the compiler always choose to call
the first version of Foo and how would I convince it to call the
second version when appropriate?
Thanks in advance for your help,
David
BTW, I am using VS.Net 7.1
#include <vector
#include
using std::cout;
template
void Foo(const Type &t)
{
cout << "Foo(const Type &)n";
}
template
void Foo(typename Container::iterator &t)
{
cout << "Foo(Container::iterator &)n";
}
int main(void)
{
std::vector
char c;
Foo(c);
Foo(v.begin());
return(0);
}
|
You have to tell the compiler explicitly with which type to instantiate
the template function:
Foo<std::vector(v.begin());
But that doesn't compile, as you try to bind a rvalue to a reference to
non-const.
So you either have to change the signature of Foo #2 to accept a const
reference, or to create a lvalue first and pass that to Foo #2:
std::vector<unsigned char>::iterator lvalue(v.begin());
Foo<std::vector(lvalue);
regards,
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Sun Dec 28, 2003 5:15 pm Post subject: Re: Templates and Functions |
|
|
David Brownell wrote in news:67e04df1.0312271516.42ff3579
@posting.google.com:
| Quote: | Given the following code, why does the compiler always choose to call
the first version of Foo and how would I convince it to call the
second version when appropriate?
Thanks in advance for your help,
David
BTW, I am using VS.Net 7.1
#include <vector
#include
using std::cout;
template
void Foo(const Type &t)
{
cout << "Foo(const Type &)n";
}
template
void Foo(typename Container::iterator &t)
|
change to
void Foo(typename Container::iterator const &t) or
void Foo(typename Container::iterator t)
if you want it to work (portably) with the result of v.begin(),
a temporary, which isn't allowed to bind to a non-const reference.
| Quote: | {
cout << "Foo(Container::iterator &)n";
}
int main(void)
{
std::vector
char c;
Foo(c);
Foo(v.begin());
|
Foo< std::vector( v.begin() );
The language simply doesn't allow for the second template function
to be matched without the template qualification I inserted above.
Though it could be made to work in some cases it would never work
if typename Container::iterator was a typedef (say for T *, as it is
in many implementaions of std::vector<>).
HTH.
Rob.
--
http://www.victim-prime.dsl.pipex.com/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Wed Dec 31, 2003 12:38 am Post subject: Re: Templates and Functions |
|
|
David Brownell wrote:
| Quote: | Given the following code, why does the compiler always choose to
call the first version of Foo
|
There are two reasons why the second version isn't selected. The
first is that template argument deduction isn't done on a function
parameter of the form typename T::U because in general there can
be many types T that each define a member U as a type alias for
the same type. The second is that v.begin() is an rvalue (it
evaluates to a temporary value) and non-constant references cannot
be bound to rvalues.
| Quote: | and how would I convince it to call the second version when
appropriate?
|
Make the function parameter type a constant reference. Make the
template argument explicit (Foo<std::vector).
<snip>
| Quote: | #include <vector
#include
using std::cout;
template
void Foo(const Type &t)
{
cout << "Foo(const Type &)n";
}
template
void Foo(typename Container::iterator &t)
{
cout << "Foo(Container::iterator &)n";
}
int main(void)
{
std::vector
char c;
Foo(c);
Foo(v.begin());
return(0);
}
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Chris ( Val ) Guest
|
Posted: Sat Jan 03, 2004 4:36 pm Post subject: Re: Templates and Functions |
|
|
"Rob Williscroft" <rtw (AT) freenet (DOT) REMOVE.co.uk> wrote
| Quote: | David Brownell wrote in news:67e04df1.0312271516.42ff3579
@posting.google.com:
|
[snip]
| Quote: | The language simply doesn't allow for the second template function
to be matched without the template qualification I inserted above.
|
[snip]
Although you could specialise it, so that the OP
can retain the syntax for 'Foo', as was desired:
typedef std::vector<unsigned char>::iterator VecIter;
template <> void Foo<VecIter>( const VecIter & t )
{
cout << "Foo(Container::iterator &)n";
}
Cheers.
Chris Val
[ 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
|
|