简体   繁体   中英

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)
{
  // 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM