C++ 从typedef数据类型中删除常量

C++ 从typedef数据类型中删除常量,c++,pointers,templates,constants,C++,Pointers,Templates,Constants,我在某个文件中定义了以下typedef: typedef const uint8_t* BufType; 在另一个文件中,我需要删除指针的恒定性。我不能使用旧的c样式转换:(uint8\u t*)。如何做到这一点 确切情况: 我有模板专门化来推断数据类型: template<Enum E> struct deduce_datatype_from {}; // Specialization template<> struct deduce_datatype_from&l

我在某个文件中定义了以下typedef:

typedef const uint8_t* BufType;
在另一个文件中,我需要删除指针的恒定性。我不能使用旧的c样式转换:
(uint8\u t*)
。如何做到这一点

确切情况: 我有模板专门化来推断数据类型:

template<Enum E>
struct deduce_datatype_from {};

// Specialization
template<>
struct deduce_datatype_from<E1> {
  typedef BufType const uint8_t*;
}
模板
结构从{}推导出{u数据类型};
//专业化
模板
结构推断出数据类型{
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; 
}
模板
void f(从::BufType buf推断出数据类型);
//功能专门化。
模板
void f(从::BufType buf推断出数据类型){
结构写入请求;
写入_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);
}
在此替代方案中,您可以在使用点直接使用
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);
std::array buf={'\0'};
BufType const cdata=buf.data();
uint8_t*数据=常量(数据);

正如一条评论所说,与所有的
const\u cast
用法一样,您需要小心不要将其应用于初始化为const对象的对象。这样做将是错误的。

请注意,如果您将const从声明为const的对象中丢弃,然后写入该对象,则您的程序将具有未定义的行为,并且是一个无效程序,编译器无需就此向您发出警告,但是可能会默默地生成损坏的代码。如果您的
推断\u数据类型\u不会返回该
常量,不是更容易吗?毕竟,添加常量非常简单。您可以使用
std::remove\u pointer
,然后使用
std::remove\u const
,最后使用
std::add\u pointer
?这将为您提供不带
常量的指针。或者,您可以在赋值之前取消对指针的引用并使用地址吗?
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);
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);