template function that accepts const and non-const

U

u.int.32.t

Is there a way to make a single template function that will accept
both const and non-const parameter types by reference without making a
copy?

For example, I can write this which will accept both, but will always
make a copy:

template<typename T1>
void accept(T1 t);

Thanks for your time.
 
R

Rolf Magnus

u.int.32.t said:
Is there a way to make a single template function that will accept
both const and non-const parameter types by reference without making a
copy?

For example, I can write this which will accept both, but will always
make a copy:

template<typename T1>
void accept(T1 t);

Thanks for your time.

Use a reference:

template<typename T1>
void accept(T1& t);
 
I

Ian Collins

u.int.32.t said:
Is there a way to make a single template function that will accept
both const and non-const parameter types by reference without making a
copy?

For example, I can write this which will accept both, but will always
make a copy:

template<typename T1>
void accept(T1 t);

Thanks for your time.
Why would you want to? If you want to accept both const and non-const
parameters by reference, the function can't modify them. So just use

template <typename T1>
void accept(const T1& t);
 
G

Gianni Mariani

u.int.32.t wrote:
....
Yes but this won't work if accept is called as:

accept(5);

For example.

Then overload accept.

template <typename T>
void accept( T & x );

template <typename T>
void accept( const T & x );

int main()
{
int i;

accept( i );
accept( 5 );
}


.... if you really want to live on the thin edge implement the const
version like this:

template <typename T>
void accept( const T & x )
{
T t(x);
accept(t);
}

.... don't do this unless you are sure that no-one will misuse it as
strange things will happen if you expect modifications to the parameter
to mean anything.
 
U

u.int.32.t

Why would you want to? If you want to accept both const and non-const
parameters by reference, the function can't modify them. So just use

template <typename T1>
void accept(const T1& t);

accept was a forwarding function which I now realize can't be done
fully without changes to the language. And it really did need to allow
mutable references.
 
G

Gianni Mariani

u.int.32.t said:
accept was a forwarding function which I now realize can't be done
fully without changes to the language. And it really did need to allow
mutable references.


NO NO .... be careful with mutable. In some cases it makes perfect
sense, in some it does not, it really depends on if the mutable elements
are part of the value or part of the management. e.g. A cache should be
mutable (because I should be able to change what things are cached even
if it's a const object), however the data in the cache should not be
mutable.

Anyhow, what was wrong with my overloaded method suggestion ?
 
S

Sylvester Hesp

Gianni Mariani said:
NO NO .... be careful with mutable. In some cases it makes perfect sense,
in some it does not, it really depends on if the mutable elements are part
of the value or part of the management. e.g. A cache should be mutable
(because I should be able to change what things are cached even if it's a
const object), however the data in the cache should not be mutable.

Uhm, I think you're misinterpreting u.int.32.t :). What he's saying has
nothing to do with the C++ keyword 'mutable', but with the meaning of the
word mutable itself, e.g., the function needs to be allowed to make changes
to the entity referenced to. From what I understand of it, he has to write a
forwarding function that is able to forward it's parameters as-is to another
(probably yet undefined) function. If you define the accept function taking
a const T&, it can't forward to functions taking a T&, and if you define
accept() taking a T&, you can't pass it a const T&. So without a change in
the language, overloading is the only way possible (C++09 will have "r-value
references" that, amongst other things, allow you to forward passed-in
function parameters to other functions as-is)

- Sylvester
 
U

u.int.32.t

NO NO .... be careful with mutable. In some cases it makes perfect sense,
[snip]

Uhm, I think you're misinterpreting u.int.32.t :). What he's saying has
nothing to do with the C++ keyword 'mutable', but with the meaning of the
word mutable itself, e.g., the function needs to be allowed to make changes
to the entity referenced to. From what I understand of it, he has to write a
forwarding function that is able to forward it's parameters as-is to another
(probably yet undefined) function. If you define the accept function taking
a const T&, it can't forward to functions taking a T&, and if you define
accept() taking a T&, you can't pass it a const T&. So without a change in
the language, overloading is the only way possible (C++09 will have "r-value
references" that, amongst other things, allow you to forward passed-in
function parameters to other functions as-is)

Yes, this is exactly it.

For now, I am probably going to do the equivalent of:

template<typename T>
void accept(T & t); // T=const T when necessary

and in the cases where I call accept like:

accept(someRvalueFromFunction())

I'll change it to:

accept(static_cast<const T&>(someRvalueFromFunction());

How does that sound?
 
I

Ian Collins

u.int.32.t said:
For now, I am probably going to do the equivalent of:

template<typename T>
void accept(T & t); // T=const T when necessary

and in the cases where I call accept like:

accept(someRvalueFromFunction())

I'll change it to:

accept(static_cast<const T&>(someRvalueFromFunction());

How does that sound?
Why can't you just overload accept for const?
 
U

u.int.32.t

Why can't you just overload accept for const?

Because accept is in really an polymorphic n-ary forwarding function.
I think it would be prohibitive to have overloads for each
permutation.

If it were just accept(T1), that would work, but its really
accept(T1,T2,T3,T4,...) etc, etc.
 
I

Ian Collins

u.int.32.t said:
Because accept is in really an polymorphic n-ary forwarding function.
I think it would be prohibitive to have overloads for each
permutation.

If it were just accept(T1), that would work, but its really
accept(T1,T2,T3,T4,...) etc, etc.
I see. I still think you are taking a risk mixing const and non-const
parameters. You'll have to find a way of making sure a const object
does not get passed to a function expecting a non-const.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,298
Messages
2,571,540
Members
48,275
Latest member
tetedenuit01

Latest Threads

Top