我在某个文件中定义了以下typedef:
typedef const uint8_t* BufType;
并且在另一个文件中,我需要删除指针的常数。我不能使用旧的C样式强制转换:(uint8_t*)
。如何实现?
精确场景:我有模板专门化来推断数据类型:
template<Enum E>
struct deduce_datatype_from {};
// Specialization
template<>
struct deduce_datatype_from<E1> {
typedef BufType const uint8_t*;
}
我在定义如下的功能模板中使用它:
template <Enum E>
void f(deduce_datatype_from<E>::BufType buf);
// function specialization.
template <>
void f<E1>(deduce_datatype_from<E1>::BufType buf) {
struct write_struct write_req;
write_req.buf = (??)buf;
}
在这种情况下,write_struct
由lib提供,但对buf
没有任何修改,因此应该是安全的。
您可以定义一个指针重载的模板函数:
template <typename T>
T& remove_const(const T& value)
{
return const_cast<T&>(value);
}
template <typename T>
T* remove_const(const T* value)
{
return const_cast<T*>(value);
}
并这样称呼:
std::array<const uint8_t, 8> buf = {'\0'};
BufType cdata = buf.data();
uint8_t* data = remove_const(data);
如果您想要一种表示结果类型的方法,即删除pointed-to类型的const
,则可以定义这样的类型特征(或在函数情况下定义模板专业化) :
template <typename T>
struct remove_pointed_to_const
{
using type = std::add_pointer_t<std::remove_const_t<std::remove_pointer_t<T>>>;
};
// This static_assert is correct.
static_assert(std::is_same<remove_pointed_to_const<BufType>::type, uint8_t*>::value);
在此替代方法中,您可以在使用时直接使用const_cast
,这可能使识别项目中所有const_cast位置更加容易:
std::array<const uint8_t, 8> buf = {'\0'};
BufType const cdata = buf.data();
uint8_t* data = const_cast<remove_pointed_to_const<BufType>::type>(data);
正如评论所说,与所有const_cast
用法一样,您需要注意不要将其应用于初始化为const对象的对象。这样做将是UB。