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 

Templates and Functions

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





PostPosted: Sun Dec 28, 2003 10:10 am    Post subject: Templates and Functions Reply with 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 <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





PostPosted: Sun Dec 28, 2003 3:53 pm    Post subject: Re: Templates and Functions Reply with quote



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





PostPosted: Sun Dec 28, 2003 5:15 pm    Post subject: Re: Templates and Functions Reply with quote





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





PostPosted: Sun Dec 28, 2003 5:15 pm    Post subject: Re: Templates and Functions Reply with quote

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() );

Quote:

return(0);
}


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





PostPosted: Wed Dec 31, 2003 12:38 am    Post subject: Re: Templates and Functions Reply with quote

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





PostPosted: Sat Jan 03, 2004 4:36 pm    Post subject: Re: Templates and Functions Reply with quote


"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
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.