Removing const-ness from a type inside template function
void foo (void *p); // library function; can't edit
template<typename T>
void Remove (T *p)
开发者_如何学Python{
// 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()`
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
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.)
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()`
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.
精彩评论