从模板内部的类型函数中删除const-ness

时间:2011-05-25 14:16:37

标签: c++ templates const

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的{​​{1}}吗? ......用法:

T*

4 个答案:

答案 0 :(得分:3)

如果你真的需要它,那就有一个boost / C ++ 0x元函数:

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

测试:https://ideone.com/L6urU

答案 1 :(得分:2)

怎么样:

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

(或者为(非)const指针进一步专门化模板。)

答案 2 :(得分:2)

这实际上是一个指向const-object的指针,并删除co​​nstness,从而使它(foo)能够改变对象。这与实际暴露的接口不一致,这意味着它在任何类型上都可以(并且预期)工作。

不仅如此,它还允许您使用实际const对象的地址来调用它,这将是未定义的行为。

相反,如果绝对需要(并保证对象不是常量),则应该在调用模板函数之前删除const ,以使其按预期工作(不改变const类型) )。

const A *p;
Remove(const_cast<A*>(p)); // error for `foo()`

答案 3 :(得分:0)

您可能还会先static_castconst void *,然后再const_castvoid *

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

这无疑是非常难看的。