实现简化的C++向量类复制 - 无法编译
Implementing a simplified C++ vector class copy - won't compile
《加速c++》第11章讨论了如何实现模板类,使用STL的vector类的简化版本作为示例。练习11-6希望我们将.erase()
和.clear()
方法添加到类中,所以首先我直接从书中复制最终代码并尝试编译,但失败了。然后,我将所有的函数定义移动到。h文件中(必要时删除Vec<T>::
等内容),并编译了我的main.cpp,它工作了。
这是我所有的代码:
main.cpp
#include <iostream>
#include "Vec.h"
using std::cout;
using std::endl;
int main()
{
Vec<int> v;
for (int i = 1; i < 10; ++i)
v.push_back(i);
for(Vec<int>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
cout << *iter << endl;
return 0;
}
Vec.h
#ifndef GUARD_Vec_h
#define GUARD_Vec_h
#include <cstddef>
#include <memory>
template <class T> class Vec {
public:
// member variables
typedef T* iterator;
typedef const T* const_iterator;
typedef std::size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
// constructors + destructors
Vec() { create(); }
explicit Vec(size_type n, const T& t = T()) { create(n, t); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
~Vec() { uncreate(); }
// methods
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
void push_back(const T& t) {
if (avail == limit)
grow();
unchecked_append(t);
}
size_type size() const { return avail - data; }
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);
void uncreate();
void grow();
void unchecked_append(const T&);
};
#endif GUARD_Vec_h
Vec.cpp
#include <algorithm>
#include <cstddef>
#include <memory>
#include "Vec.h"
using std::allocator;
using std::max;
using std::uninitialized_copy;
using std::uninitialized_fill;
using std::ptrdiff_t;
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;
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 = 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;
}
template <class T> void Vec<T>::grow()
{
size_type new_size = max(2 * (limit - data), ptrdiff_t(1));
iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data, avail, new_data);
uncreate();
data = new_data;
avail = new_avail;
limit = data + new_size;
}
template <class T> void Vec<T>::unchecked_append(const T& val)
{
alloc.construct(avail++, val);
}
为什么不能编译?
问题是任何和所有的模板函数。当您编写一个Template函数时,编译器实例化模板——也就是说,它创建一个特定版本的函数,其中包含运行代码所需的类型。所以当你调用
Vec<int> v;
编译器为Vec和您调用的任何该类型的函数生成代码。编译器在为主文件编写代码时需要访问模板化的函数定义,因为在链接其他文件之前,它必须知道为目标文件编写什么样的代码。
相关文章:
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 为什么在直接初始化和赋值中传递 lambda 而不是在复制初始化中传递 lambda 时会编译?
- 为什么在使用转换构造函数编译代码时需要 const 复制构造函数?
- 模板函数,它使用 n_copy 复制前 n 个元素形成一个向量,另一个向量导致编译错误
- 即使使用-fno-elide-constructors编译,复制省略似乎也会发生
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 显式删除从不使用复制构造函数,导致编译错误
- 复制构造函数奇怪的编译错误
- 为什么复制此类中的构造函数、运算符=和引用存在编译问题
- 程序无法编译,即使我正在从书中复制代码
- 使用VS2008编译的C/C++中存在结构复制问题
- 显式复制构造函数编译错误
- 为什么在复制rapidjson::Document时出现链接器错误而不是编译错误
- 返回仅移动类型编译,即使复制构造函数不可用
- 在编译时将 mpl::vector_c 复制到静态数组
- 对具有不可复制值的 stl 容器使用提升序列化时出现编译错误
- boost::p ython:编译失败,因为复制构造函数是私有的
- 由于复制构造函数而导致的编译错误
- 值的赋值运算符未使用显式复制构造函数进行编译
- 不可移动-不可复制对象的向量的移动分配不会编译