templating constness

  • Thread starter Thread starter Olav
  • Start date Start date
O

Olav

Hi
I wonder if it is possible to have templates expand based on constness,
something like:

template<typename A, typename B>copy( A &a, B &b);

becoming:

copy( const class AClass &a, class BClass &b );

or

copy( class AClass &a, const class BClass &b );

based on arguments.

The purpose of this would be to be able to write something like

template<typename A, typename B>copy( A &a, B &b)
{
copy( a.name, b.name);
copy( a.value, b.value)
}

And have the constness of the arguments decide the direction.

Adding a third parameter specifying direction would be OK.
The main thing is to be able to use consting without const_cast's.

Thanks
Olav
 
Hi
I wonder if it is possible to have templates expand based on constness,
something like:

template<typename A, typename B>copy( A &a, B &b);

becoming:

copy( const class AClass &a, class BClass &b );

or

copy( class AClass &a, const class BClass &b );

based on arguments.

The purpose of this would be to be able to write something like

template<typename A, typename B>copy( A &a, B &b)
{
copy( a.name, b.name);
copy( a.value, b.value)
}

And have the constness of the arguments decide the direction.

That sounds dangerous to me. Doesn't the caller of copy know the
direction? They should!
Adding a third parameter specifying direction would be OK.
The main thing is to be able to use consting without const_cast's.

Overloading would do it I think:

template <typename A, typename B>
void copy_lhs_to_rhs(A const& a, B& b); //implement however


template<typename A, typename B>
inline void copy( A &a, B const&b)
{
copy_lhs_to_rhs(b, a);
}

template<typename A, typename B>
inline void copy( A const& a, B& b)
{
copy_lhs_to_rhs(a, b);
}

That also nicely will report an ambiguity if you try to copy two
non-const objects, and an error if you try to copy two const objects.

However, I don't quite see the point of this - you always know which
way you're copying.

Tom
 
Thanks, will have a look - it might work!
However, I don't quite see the point of this - you always know which
way you're copying.

Tom
Its not really copying - its serialization and de-serialization, and its
very practical
to have every class mapped in one method instead of two.

Olav
 
template<typename A, typename B>
inline void copy( A &a, B const&b)
{
copy_lhs_to_rhs(b, a);
}


Think it would fail here, as the two types are different.
The best solution I have found so far is:

void Process(A &a, XMLNode &xmlNode, LoadStoreAction action )

With templates doing deconst-casts when necesarry.

The second type is actually always XMLNode (though ideally with and without
const),
while the left side is different classes

Thanks
Olav
 
Think it would fail here, as the two types are different.

Why would that make it fail? copy_lhs_to_rhs is a templated function
that can take any pair of types, and template argument deduction will
deduce the correct types for A and B there (and they will be A=copy's
B and B=copy's A!)

Tom
 
tom_usenet said:
Why would that make it fail? copy_lhs_to_rhs is a templated function
that can take any pair of types, and template argument deduction will
deduce the correct types for A and B there (and they will be A=copy's
B and B=copy's A!)

Tom

The code might be correct, but the purpose of the exercise is to have only
one function pr. class.


I think with your code I would have to implement, for a class A:

void copy_lhs_to_rhs(A const& a, XMLNode & xmlNode);

and

void copy_lhs_to_rhs(const XMLNode & xmlNode, A & a );

Disagree?
 
The code might be correct, but the purpose of the exercise is to have only
one function pr. class.


I think with your code I would have to implement, for a class A:

void copy_lhs_to_rhs(A const& a, XMLNode & xmlNode);

and

void copy_lhs_to_rhs(const XMLNode & xmlNode, A & a );

Disagree?

Ahh, so you do need a "direction" parameter of some kind, and
appropriate const_casts. I'm not convinced that having one shared
function is going to improve your code at all though. In the past I've
tried this kind of thing and ended up going back to two functions just
to get rid of all the const_casts and because only the read function
needed to be virtual. Any code that contains const_cast is obviously
error prone, particularly if the const_cast happened in a different
function.

Tom
 
tom_usenet said:
On Thu, 22 Jul 2004 16:59:46 +0200, "Olav"


Ahh, so you do need a "direction" parameter of some kind, and
appropriate const_casts. I'm not convinced that having one shared
function is going to improve your code at all though. In the past I've
tried this kind of thing and ended up going back to two functions just
to get rid of all the const_casts and because only the read function
needed to be virtual. Any code that contains const_cast is obviously
error prone, particularly if the const_cast happened in a different
function.
The const casting can be done in a few templates (not pr class), with an
assert on direction it is quite safe.

Also, the problem can be solved by passing around two refs: one const and
one non-const:

template<class TDomainClass>
void Process(
TDomainClass *obj_t,
TDomainClass *const_obj_t,
XMLNode *xmlNode,
// XMLNode *const_xmlNode,
LoadStoreAction action)
{

Pointers instead of refs as at least the non-const parameters might be null.

Olav
 
Back
Top