【问题标题】:How to cast const pointer to non-const pointer in c++?如何在 C++ 中将 const 指针转换为非 const 指针?
【发布时间】:2020-08-10 15:04:07
【问题描述】:

我想用std::initializer_list实现构造函数,我试过了:

#include <initializer_list>

template <class T>
class Vec
{
public:
    typedef T *iterator;
    typedef T *const const_iterator;
    typedef T value_type;
    Vec(std::initializer_list<T> init)
    {
        create(init);
    } 
    ...
private:
    iterator data;
    iterator avail;
    iterator limit;
    void create(std::initializer_list<T> init);
    ...
}

template<class T> void Vec<T>::create(std::initializer_list<T> init)
{
    data = init.begin();
    limit = avail = init.end();
}

但是当我尝试使用它时:

#include "vec2.hpp"

int main()
{
    Vec<int> v({ 1, 2, 3, 4 });
}

我很惊讶 std::initializer_list::begin()end() 迭代器是 const iterator,不可写 iterator(就像所有其他容器一样,std::vectorbegin() 上返回一个可写迭代器,@ 也是如此987654330@ 和许多其他人)。所以我得到了一个错误:

data = init.begin();
vec2.hpp:138:19: error: invalid conversion from ‘std::initializer_list<int>::const_iterator’ {aka ‘const int*’} to ‘Vec<int>::iterator’ {aka ‘int*’} [-fpermissive]

所以现在我需要将T* const begin() 转换为T* begin(),但不知道如何。我试过了

template<class T> void Vec<T>::create(std::initializer_list<T> init)
{
    data = const_cast<T*>(init.begin());
    limit = avail = const_cast<T*>(init.end());
}

但后来我得到了:

free(): invalid pointer
Aborted

那我该怎么办?

【问题讨论】:

  • 您很惊讶,因为您根本没有阅读初始化列表的工作原理?为什么同一种类型会有三种不同的 typedef?
  • 仅供参考,关联容器不允许您通过其迭代器进行编写。不仅仅是initializer_list
  • 仅供参考:typedef T *const const_iterator; 不会做你认为它会做的事。它将创建一个无法更改的迭代器,但您仍然可以更改它指向的值。
  • 这并没有解决问题,但必须抛弃 const-ness 通常是设计问题的标志。你不能用代码解决设计问题。你必须修复设计。

标签: c++ constructor casting constants


【解决方案1】:

初始化器列表是短期序列的轻量级代理对象,它们不应该用于将数据写入这些结构或保留它们以供将来使用。

如果您想实现自己的接受initializer listvector 类构造函数,则必须将提供的initializer_list 中的数据复制 到您自己的存储中。否则你很可能会得到 dangling 迭代器。

【讨论】:

  • 它们是什么? dangling iterators?
  • @milanHrabos 像 dangling 指针和 dangling 引用,悬空迭代器指向不再存在的对象。
猜你喜欢
  • 2017-05-15
  • 2013-10-20
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2011-01-14
相关资源
最近更新 更多