469,574 Members | 1,643 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,574 developers. It's quick & easy.

ambient swap template not found.

Hi folks,
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}

};

}

int main ( void ) {
xxx::stupid< xxx::empty > a, b;
a.swap(b); // line 22
}
The compiler complains:

In member function 'void xxx::stupid<T>::swap(xxx::stupid<T>&)
[with T = xxx::empty]':
file.cc:22: instantiated from here
file.cc:13: error: no matching function for call to
'xxx::stupid<xxx::empty>:
:swap(xxx::empty&, xxx::empty&)'
file.cc:12: note: candidates are: void xxx::stupid<T>::swap(xxx::stupid<T>&)
[with T = xxx::empty]
Obviously, the presence of the local swap-method in stupid<T> prevents the
compiler from looking outside for other possible swaps. I was under the
impression that the namespace where T (in this case xxx::empty) is defined
would be searched for a match. But that apparently does not happen. Why is
that?
Best

Kai-Uwe Bux
Oct 8 '05 #1
7 1551
Kai-Uwe Bux wrote:
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}

};

}

int main ( void ) {
xxx::stupid< xxx::empty > a, b;
a.swap(b); // line 22
}
The compiler complains:

In member function 'void xxx::stupid<T>::swap(xxx::stupid<T>&)
[with T = xxx::empty]':
file.cc:22: instantiated from here
file.cc:13: error: no matching function for call to
'xxx::stupid<xxx::empty>:
swap(xxx::empty&, xxx::empty&)' file.cc:12: note: candidates are: void
xxx::stupid<T>::swap(xxx::stupid<T>&) [with T = xxx::empty]
Obviously, the presence of the local swap-method in stupid<T>
prevents the compiler from looking outside for other possible swaps.


No, it does not prevent it from looking. It prevents the compiler
from seeing it.
I was under the impression that the namespace where T (in this case
xxx::empty) is defined would be searched for a match. But that
apparently does not happen. Why is that?

It's called "name hiding", I believe. 'swap' name in the struct
'stupid' scope _hides_ the one in the namespace scope, so while
you're in 'xxx::stupid::swap', the other one is simply invisible.

V
Oct 8 '05 #2
Victor Bazarov wrote:
Kai-Uwe Bux wrote:
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}

};

}
[snip]
I was under the impression that the namespace where T (in this case
xxx::empty) is defined would be searched for a match. But that
apparently does not happen. Why is that?

It's called "name hiding", I believe. 'swap' name in the struct
'stupid' scope _hides_ the one in the namespace scope, so while
you're in 'xxx::stupid::swap', the other one is simply invisible.

Thanks a lot for the explanation. However, that leaves me with a problem:
how to tell the template stupid<T> which swap to use. I considered:

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) {
std::swap( this->data, other.data );
}

};

This, I think, will not find specialized/overloaded version of swap for
types not declared in namespace std; and I cannot dump my stuff in there.

Thus, I did:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
void global_swap ( T & a, T & b ) {
swap( a, b );
}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) {
global_swap( this->data, other.data );
}

};

}

This will find the appropriate swap by looking at the argument type. But
introducing the forwarding function "global_swap" seems clumsy. I would
appreciate suggestions for how to improve upon this.
Thanks again

Kai-Uwe Bux

Oct 8 '05 #3
Kai-Uwe Bux wrote:
[..]
Thanks a lot for the explanation. However, that leaves me with a
problem: how to tell the template stupid<T> which swap to use. I
considered:

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) {
std::swap( this->data, other.data );
}

};

This, I think, will not find specialized/overloaded version of swap
for types not declared in namespace std; and I cannot dump my stuff
in there.
Yes, you can.

"17.4.3.1 Reserved names
[...]. A program may add template specializations for any
standard library template to namespace std. [...]"

So, you're totally allowed to specialise 'swap' for your class 'empty'
and put it in 'std' namespace.
[...]


V
Oct 9 '05 #4

"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:di**********@murdoch.acc.Virginia.EDU...
Hi folks,
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}


how bout xxx::swap instead?

Jon
Oct 9 '05 #5
Jon Slaughter wrote:
"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:di**********@murdoch.acc.Virginia.EDU...
Hi folks,
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}


how bout xxx::swap instead?


That would not allow using 'std::swap' for T other than 'empty'.

V
Oct 9 '05 #6

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:af********************@comcast.com...
Jon Slaughter wrote:
"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:di**********@murdoch.acc.Virginia.EDU...
Hi folks,
I am still struggling with the rules for name lookup.
Please consider:

namespace xxx {

struct empty {};

void swap ( empty & a, empty & b ) {}

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) { // line 12
swap( this->data, other.data ); // line 13
}


how bout xxx::swap instead?


That would not allow using 'std::swap' for T other than 'empty'.

V


Then he needs to specialize stupid::swap if T is of empty type to use
xxx::swap?

basicaly

if T is of type empty then use xxx::swap else use std::swap

or whatever
Oct 9 '05 #7
Victor Bazarov wrote:
Kai-Uwe Bux wrote:
[..]
Thanks a lot for the explanation. However, that leaves me with a
problem: how to tell the template stupid<T> which swap to use. I
considered:

template < typename T >
struct stupid {

T data;

void swap ( stupid & other ) {
std::swap( this->data, other.data );
}

};

This, I think, will not find specialized/overloaded version of swap
for types not declared in namespace std; and I cannot dump my stuff
in there.


Yes, you can.

"17.4.3.1 Reserved names
[...]. A program may add template specializations for any
standard library template to namespace std. [...]"

So, you're totally allowed to specialise 'swap' for your class 'empty'
and put it in 'std' namespace.


Great! Thanks for that crucial piece of information.
Best

Kai-Uwe Bux
Oct 9 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Davis King | last post: by
8 posts views Thread by surrealtrauma | last post: by
2 posts views Thread by ma740988 | last post: by
4 posts views Thread by Niels Dekker (no reply address) | last post: by
9 posts views Thread by ma740988 | last post: by
1 post views Thread by panzhiyong | last post: by
11 posts views Thread by Dennis Jones | last post: by
reply views Thread by christian2.schmidt | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.