Удаление констант из типа внутри функции шаблона - PullRequest
1 голос
/ 25 мая 2011
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 ?
}

У меня есть несколько функций, таких как Remove(), его также можно вызывать с помощью const T*, что не соответствует foo(void*) Без перегрузки / специализации Remove() можно ли удалить const ness T*? ... Использование:

const int *p;
Remove(p); // error related to `foo()`

Ответы [ 4 ]

3 голосов
/ 25 мая 2011

Если вам это действительно нужно, для этого есть метафункция boost / C ++ 0x:

template<typename T>
void Remove (T *p)
{
    foo( const_cast< typename std::remove_const<T>::type *> (p) );
}

тест: https://ideone.com/L6urU

2 голосов
/ 25 мая 2011

Это будет эффективно брать указатель на const-объект и удалять константу, таким образом делая его (foo) способным мутировать объект.Это было бы несовместимо с действительным открытым интерфейсом, который подразумевает, что он работает одинаково (и ожидаемо) для любого типа.

Не только это, но это позволит вам вызывать его с адресом фактически константного объекта,Поведение будет неопределенным(не мутирующие константные типы).

const A *p;
Remove(const_cast<A*>(p)); // error for `foo()`
2 голосов
/ 25 мая 2011

Как насчет:

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); }
};

Использовать его следующим образом:

template<typename T>
void Remove (T* p) {
    foo(&nonconst<T>::value(*p));
}

(или дополнительно специализировать шаблон для (не) константных указателей.)

0 голосов
/ 07 июля 2014

Вы могли бы также сначала сделать static_cast до const void *, затем const_cast, что до void *:

template<typename T>
void Remove (T *p)
{
    foo(const_cast<void*> (static_cast <const void*> (p)));
}

Это по общему признанию довольно уродливо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...