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 const function name resolution

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





PostPosted: Tue Aug 29, 2006 3:04 am    Post subject: Templates and const function name resolution Reply with quote



Hello,

I have the following class C and the function F:

class C
{
public:
const vector<int>& GetV() const { return m_v; }
private:
vector<int>& GetV() { return m_v; }
vector<int> m_v;
};

template<class T1, class T2>
void F(const typename vector<T1>::iterator& first,
const typename vector<T1>::iterator& last)
{
for (vector<T1>::iterator it = first; it != last; ++it)
{
const vector<T2>& v = it->GetV();
}
}

I am trying to call F as:

....
vector<C> v;
F<C, int>(v.begin(), v.end());
....

But this does not compile (with MS VC++ 7) - the compiler refuses to
find the public GetV() function, instead it finds the private one.

However, if I replace
const vector<T2>& v = it->GetV();
with
const vector<T2>& v = vector<T1>::const_iterator(it)->GetV();

the code compiles.

I am wondering why the code as presented above does not compile and how
can I make it compile without introducing const iterator?

Thanks,

Dimitar


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Bo Persson
Guest





PostPosted: Tue Aug 29, 2006 4:05 am    Post subject: Re: Templates and const function name resolution Reply with quote



"Dimitar" <dimitar.gospodinov (AT) gmail (DOT) com> skrev i meddelandet
news:1156791128.327334.276570 (AT) p79g2000cwp (DOT) googlegroups.com...
Quote:
Hello,

I have the following class C and the function F:

class C
{
public:
const vector<int>& GetV() const { return m_v; }
private:
vector<int>& GetV() { return m_v; }
vector<int> m_v;
};

template<class T1, class T2
void F(const typename vector<T1>::iterator& first,
const typename vector<T1>::iterator& last)
{
for (vector<T1>::iterator it = first; it != last; ++it)
{
const vector<T2>& v = it->GetV();
}
}

I am trying to call F as:

...
vector<C> v;
F<C, int>(v.begin(), v.end());
...

But this does not compile (with MS VC++ 7) - the compiler refuses to
find the public GetV() function, instead it finds the private one.

Yes, the compiler has to first select candidates for overload
resolution, and if one is selected, check if it is also accessible.

Quote:

However, if I replace
const vector<T2>& v = it->GetV();
with
const vector<T2>& v = vector<T1>::const_iterator(it)->GetV();

the code compiles.

I am wondering why the code as presented above does not compile and
how
can I make it compile without introducing const iterator?

If you have both a const and a non-const function, the call is based
on the const-ness of the object you call it for ('*it' in this case).

You have several options, like
- make 'it' a const iterator in the for loop
- remove the private overload
- rename the const one GetConstV


Bo Persson



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Jens Theisen
Guest





PostPosted: Tue Aug 29, 2006 4:06 am    Post subject: Re: Templates and const function name resolution Reply with quote



Dimitar wrote:
Quote:
I am wondering why the code as presented above does not compile and how
can I make it compile without introducing const iterator?

Access control comes after overload resolution: If the non-const version
is a better match, then it will be taken; and if that's not possible
because it being private, it's an error.

If it's called on a non-const object, it is a better match, and
otherwise the const version is the only match.

If you use const_iterators, the value_type (what you get when
dereferencing the iterator) is C const&, so the const version will be
taken and with iterators it's the non-const version.

This is desirable: You should use const_iterators when you don't want to
modify your object.

Jens

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Tue Aug 29, 2006 11:51 pm    Post subject: Re: Templates and const function name resolution Reply with quote

Dimitar wrote:

Quote:
I have the following class C and the function F:

class C
{
public:
const vector<int>& GetV() const { return m_v; }
private:
vector<int>& GetV() { return m_v; }
vector<int> m_v;
};

template<class T1, class T2
void F(const typename vector<T1>::iterator& first,
const typename vector<T1>::iterator& last)
{
for (vector<T1>::iterator it = first; it != last; ++it)
{
const vector<T2>& v = it->GetV();
}
}

I am trying to call F as:

...
vector<C> v;
F<C, int>(v.begin(), v.end());
...

But this does not compile (with MS VC++ 7) - the compiler
refuses to find the public GetV() function, instead it finds
the private one.

It finds both. It then uses overload resolution to choose the
best match. In this case, the non-const version. (A non-const
function always beets a const function, if it can be called with
the given arguments).

Finally, having chosen the function, the compiler checks whether
it is accessible. It isn't, so you have an error.

Quote:
However, if I replace
const vector<T2>& v = it->GetV();
with
const vector<T2>& v = vector<T1>::const_iterator(it)->GetV();

the code compiles.

Yes. Because the non-const function cannot be called, and is
not part of the overload set.

Quote:
I am wondering why the code as presented above does not
compile and how can I make it compile without introducing
const iterator?

Change the name of one of the functions. It is almost always a
bad idea for functions with the same name to have different
access rights.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Greg Herlihy
Guest





PostPosted: Wed Aug 30, 2006 5:13 pm    Post subject: Re: Templates and const function name resolution Reply with quote

kanze wrote:
Quote:
Dimitar wrote:

I have the following class C and the function F:

class C
{
public:
const vector<int>& GetV() const { return m_v; }
private:
vector<int>& GetV() { return m_v; }
vector<int> m_v;
};

template<class T1, class T2
void F(const typename vector<T1>::iterator& first,
const typename vector<T1>::iterator& last)
{
for (vector<T1>::iterator it = first; it != last; ++it)
{
const vector<T2>& v = it->GetV();
}
}
....

I am wondering why the code as presented above does not
compile and how can I make it compile without introducing
const iterator?

Change the name of one of the functions. It is almost always a
bad idea for functions with the same name to have different
access rights.

I would go further and question whether declaring a private, accessor
method makes much sense in the first place. After all, any context in
which the private GetV() method could be called is also a context that
that enjoys direct access to the private m_v member variable. And if
C's implemention cannot handle its own m_v data member according to its
own specifications, then there's little chance that any other code in
the program will do any better.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Thu Aug 31, 2006 8:00 pm    Post subject: Re: Templates and const function name resolution Reply with quote

Greg Herlihy wrote:
Quote:
kanze wrote:
Dimitar wrote:

I have the following class C and the function F:

class C
{
public:
const vector<int>& GetV() const { return m_v; }
private:
vector<int>& GetV() { return m_v; }
vector<int> m_v;
};

template<class T1, class T2
void F(const typename vector<T1>::iterator& first,
const typename vector<T1>::iterator& last)
{
for (vector<T1>::iterator it = first; it != last; ++it)
{
const vector<T2>& v = it->GetV();
}
}
...

I am wondering why the code as presented above does not
compile and how can I make it compile without introducing
const iterator?

Change the name of one of the functions. It is almost
always a bad idea for functions with the same name to have
different access rights.

I would go further and question whether declaring a private,
accessor method makes much sense in the first place. After
all, any context in which the private GetV() method could be
called is also a context that that enjoys direct access to the
private m_v member variable. And if C's implemention cannot
handle its own m_v data member according to its own
specifications, then there's little chance that any other code
in the program will do any better.

In a simple case like the above, I would agree. On the other
hand, I've used private accessors for objects that were lazily
constructed, and I could see there use any time there was a
chance that the function do more than just return the immediate
object.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


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