Reputation: 69978
void foo (void *p); // library function; can't edit
template<typename T>
void Remove (T *p)
{
// main code
foo(p); // Can we remove const ness of T here ?
}
I have multiple functions like Remove()
, it can be called with const T*
also, which will not match with foo(void*)
. Without overloading/specializing Remove()
can I remove the const
ness of T*
? ... Usage:
const int *p;
Remove(p); // error related to `foo()`
Upvotes: 1
Views: 7622
Reputation: 285
You might also first do a static_cast
to const void *
then const_cast
that to void *
:
template<typename T>
void Remove (T *p)
{
foo(const_cast<void*> (static_cast <const void*> (p)));
}
It's admittedly quite ugly.
Upvotes: 0
Reputation: 47408
If you really need it, there's a boost/C++0x metafunction for that:
template<typename T>
void Remove (T *p)
{
foo( const_cast< typename std::remove_const<T>::type *> (p) );
}
test: https://ideone.com/L6urU
Upvotes: 3
Reputation: 96233
That would effectively be taking a pointer-to-const-object, and removing the constness thus making it (foo
) able to mutate the object. This would be inconsistent with the actual exposed interface which implies that it works equally (and expectedly) on any type.
Not only that, but it would allow you to call it with the address of an actually const object which would be undefined behavior.
Instead, you should, if absolutely needed (and guarantee that the object isn't const) remove the constness before calling the template function so that it works as expected (not mutating const types).
const A *p;
Remove(const_cast<A*>(p)); // error for `foo()`
Upvotes: 2
Reputation: 545518
How about:
template <typename T>
struct nonconst {
static T& value(T& value) { return value; }
};
template <typename T>
struct nonconst<T const> {
static T& value(T const& value) { return const_cast<T&>(value); }
};
Use it as follows:
template<typename T>
void Remove (T* p) {
foo(&nonconst<T>::value(*p));
}
(Or specialise the template further for (non-)const pointers.)
Upvotes: 2