【问题标题】:remove const from a typedef datatype [duplicate]从 typedef 数据类型中删除 const [重复]
【发布时间】:2020-01-05 18:07:25
【问题描述】:

我在某个文件中定义了以下 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 没有发生任何修改,因此应该是安全的。

【问题讨论】:

  • 请注意,如果您将 const 从声明为 const 的对象中转换出来,然后写入该对象,您的程序将具有未定义的行为并且是无效程序并且编译器是 not 需要警告您,但可能会默默地生成损坏的代码。
  • 如果您的deduce_datatype_from 不返回const,这不是更容易吗?毕竟,添加 const 非常简单。
  • 您可以使用std::remove_pointer,然后是std::remove_const,最后是std::add_pointer?这将为您提供不带const 的指针。或者,您可以在分配之前取消引用指针并使用地址吗?

标签: c++ pointers templates constants


【解决方案1】:

你可以定义一个为指针重载的模板函数:

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。

【讨论】:

    猜你喜欢
    • 2019-07-25
    • 2013-10-30
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    相关资源
    最近更新 更多