【发布时间】: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::vector 在 begin() 上返回一个可写迭代器,@ 也是如此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