【发布时间】:2014-08-12 08:50:40
【问题描述】:
我对 C++ 还很陌生,作为学习练习,我正在创建自己的简单矢量类。
它似乎工作得很好,除非我创建一个 Vec 对象试图使用
Vec(size_type n, const T& val = T()) 构造函数,它想使用应该采用两个迭代器/指针的模板化构造函数,并给我错误。
我相信我理解为什么会发生这种情况,但我想不出一种方法可以在不改变类的使用方式的情况下减少歧义。我想保持与 std::vector 相同的用法。
如何调用正确的构造函数? std::vector 是如何避免这个问题的?
Vec.h
//#includes: <algorithm> <cstddef> <memory>
template <class T> class Vec
{
public:
//typedefs for iterator, size_type....
//just used T* for iterator
Vec() { create(); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
explicit Vec(size_type n, const T& val = T()) { create(n, val); }
template <class InputIt>
Vec(InputIt first, InputIt last) { create(first, last); }
~Vec() { uncreate(); }
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
Vec& operator=(const Vec&);
//functions such as begin(), size(), etc...
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
template <class InputIt>
void create(InputIt first, InputIt last)
{
data = alloc.allocate(last - first);
limit = avail = std::uninitialized_copy(first, last, data);
}
void uncreate();
void grow();
void unchecked_append(const T&);
};
template <class T>
Vec<T>& Vec<T>::operator=(const Vec& rhs)
{
if (&rhs != this)
{
uncreate();
create(rhs.begin(), rhs.end());
}
return *this;
}
template <class T> void Vec<T>::create()
{
data = avail = limit = 0;
}
template <class T> void Vec<T>::create(size_type n, const T& val)
{
data = alloc.allocate(n);
limit = avail = data + n;
std::uninitialized_fill(data, limit, val);
}
template <class T>
void Vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = std::uninitialized_copy(i, j, data);
}
template <class T> void Vec<T>::uncreate()
{
if (data)
{
iterator it = avail;
while (it != data)
alloc.destroy(--it);
alloc.deallocate(data, limit - data);
}
data = limit = avail = 0;
}
//left out what I didn't think was relevant
除了我上面提到的情况外,它似乎工作正常。
main.cpp
#include "Vec.h"
main()
{
Vec<int> v1(10, 100);
}
我收到错误:
||=== 构建:在 Vec 类中调试(编译器:GNU GCC 编译器)===| c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h||在'_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = int; _ForwardIterator = int*]':| F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\Vec.h|58|需要来自 'void Vec::create(InputIt, InputIt) [with InputIt = int; T = int]'| F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\Vec.h|24|需要来自 'Vec::Vec(InputIt, InputIt) [with InputIt = int; T = int]'| F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\main.cpp|9|从这里需要| c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h|113|错误:'struct std: 中没有名为'value_type'的类型: :iterator_traits'| ||=== 构建失败:1 个错误,4 个警告(0 分钟,0 秒)===|这是我第一次在这里提问。我希望我问得正确并提供了足够的信息。如果我在此过程中犯了错误,请告诉我,感谢您提供的任何帮助。
编辑:
对于任何想知道我最终做了什么的人。我更改了模板化构造函数,以便它不会被算术参数调用(因为它仅用于迭代器/指针)。
template <class InputIt>
Vec(InputIt first, InputIt last,
typename std::enable_if<!std::is_arithmetic<InputIt>::value>::type* = 0) {create(first, last); }
它似乎工作正常,但我实际上对 enable_if 不是很熟悉,所以如果有人知道这种方法有任何危险,请告诉我。
【问题讨论】:
-
Vec(const Vec& v) { create(v.begin(), v.end(); }中缺少一个)。 -
@R Sahu:这只是帖子上的一个错字,而不是真正的程序。感谢您指出这一点。
-
解决方法
Vec<int> v1(Vec<int>::size_type(10), 100); -
@pmr 为什么不起作用?
-
@NeilKirk 谢谢,确实有效。有点笨拙,但解决了问题。
标签: c++ vector constructor