gpt4 book ai didi

c++ - 实现简化的 C++ vector 类拷贝 - 无法编译

转载 作者:太空宇宙 更新时间:2023-11-04 14:19:47 25 4
gpt4 key购买 nike

Accelerated C++ 的第 11 章介绍了模板类的实现,使用 STL vector 类的简化版本作为示例。练习 11-6 希望我们添加 .erase().clear()类的方法,所以首先我直接从书上复制最终代码并尝试编译,但失败了。然后,我将所有函数定义移动到 .h 文件中(根据需要删除 Vec<T>:: 等内容)并只编译我的 main.cpp,它起作用了。

这是我所有的代码:

主要.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);
}

为什么不能编译?

最佳答案

问题出在所有模板函数上。当您编写模板函数时,编译器实例化 模板——也就是说,它创建一个特定版本的函数,其中包含运行代码所需的类型。所以当你打电话时

Vec<int> v;

编译器为 Vec 和您调用的该类型的任何函数生成代码。编译器在为主文件编写代码时需要访问模板化函数定义,因为它必须在链接其他文件之前知道为目标文件编写什么样的代码。

关于c++ - 实现简化的 C++ vector 类拷贝 - 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8527843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com