简体   繁体   English

从模板 function 内的类型中删除 const-ness

[英]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*) .我有多个函数,比如Remove() ,它也可以用const T*调用,这与foo(void*)不匹配。 Without overloading/specializing Remove() can I remove the const ness of T* ?如果不重载/专门化Remove()我可以删除T*const吗? ... Usage: ... 用法:

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

If you really need it, there's a boost /C++0x metafunction for that:如果你真的需要它,这里有一个boost /C++0x 元函数:

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

test: https://ideone.com/L6urU测试: 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.) (或者进一步将模板专门用于(非)const 指针。)

That would effectively be taking a pointer-to-const-object, and removing the constness thus making it ( foo ) able to mutate the object.这将有效地获取一个指向常量对象的指针,并删除常量,从而使其( foo )能够改变 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.不仅如此,它还允许您使用实际 const object 的地址来调用它,这将是未定义的行为。

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).相反,如果绝对需要(并保证 object 不是 const),您应该在调用模板 function之前删除 const 以便它按预期工作(而不是改变 const 类型)。

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 * :您也可以先对const void *进行static_cast ,然后对void * * 进行const_cast

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

It's admittedly quite ugly.不可否认,它非常丑陋。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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