C++初學者,VS2013遇到error LNK1120,請問如何解決?

是依照vector和string寫兩個新的類Vec和Str。

是先寫的Vec,Vec.h和Vec-related.cpp單獨編譯是沒有問題的,加上了Str就出現這個問題了。

在網上搜過這個問題了,也在編程新手C++求助,VS2013出現fatal error LNK1120提過問,依照得到的答案深入不下去。。

只有看過一本C語言的基礎,純自學,實在不知道怎麼解決這個問題了,尋求幫助。先謝謝各位了!

是《Accelerated C++》書中的代碼,代碼如下:

Vec.h:

#ifndef GUARD_Vec_h
#define GUARD_Vec_h

#include &
#include &

template & class Vec {

public:
typedef T* iterator;
typedef const T* const_iterator;
typedef size_t size_type;
typedef T value_type;
typedef T reference;
typedef const T const_reference;
typedef std::ptrdiff_t difference_type; //ptrdiff_t &

Vec() { create(); }
explicit Vec(size_type n, const T t = T()) { create(n, t); }

Vec(const Vec v) { create(v.begin(), v.end()); }
Vec operator=(const Vec); // 單獨定義
~Vec() { uncreate(); }

void clear() { uncreate(); }

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& 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

Vec-related.cpp

#include &
#include &
#include "Vec.h"

template &
Vec& Vec&::operator=(const Vec rhs)
{
if (rhs != this) {
uncreate();
create(rhs.begin(), rhs.end());
}
return *this;
}

template & void Vec&::create()
{
data = avail = limit = 0;
}

template & void Vec&::create(size_type n, const T val)
{
data = alloc.allocate(n);
limit = avail = data + n;
uninitialized_fill(data, limit, val);
}

template &
void Vec&::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = uninitialized_copy(i, j, data);
}

template & void Vec&::uncreate()
{
if (data) {
iterator it = avail;
while (it != data)
alloc.destroy(--it);

alloc.deallocate(data, limit - data);
}
data = limit = avail = 0;
}

template & void Vec&::grow()
{
//when growing, allocate twice as much space as currently in use
size_type new_size = max(2 * (limit - data), ptrdiff_t(2));

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 & void Vec&::unchecked_append(const T val)
{
alloc.construct(avail++, val);
}

Str.h:

#include "Vec.h"
#include &
#include &
#include &
#include &

class Str {
//class 的{和第一個保護標籤之間的成員都是private的
friend std::istream operator&>&>(std::istream, Str);
public:
Str operator+=(const Str s) {
std::copy(s.data.begin(), s.data.end(), std::back_inserter(data));
return *this;
}

typedef Vec&::size_type size_type;

Str() {}
Str(size_type n, char c) : data(n, c) {}
Str(const char* cp) {
std::copy(cp, cp + strlen(cp), std::back_inserter(data));
}

template & Str(In b, In e) {
std::copy(b, e, std::back_inserter(data));
}

size_type size() const { return data.size(); }
char operator[](size_type i) { return data[i]; }
const char operator[](size_type i) const { return data[i]; }

private:
Vec& data;
};

std::ostream operator&<&<(std::ostream, const Str); Str operator+(const Str s, const Str t);

Str-related.cpp

#include "Str.h"
#include "Vec.h"

using namespace std;
ostream operator&<&<(ostream os, const Str s) { for (Str::size_type i = 0; i != s.size(); ++i) os &<&< s[i]; return os; } istream operator&>&>(istream is, Str s)
{
s.data.clear();

char c;
while (is.get(c) isspace(c))
;
if (is) {
do s.data.push_back(c);
while (is.get(c) !isspace(c));

if (is)
is.unget();
}
return is;
}

Str operator+(const Str s, const Str t)
{
Str r = s;
r += t;
return r;
}

Source.cpp:

int main()
{}


謝邀,親,這是模板的實現,怎麼能分開呢?

把Vec-related.cpp的東西移到Vec.h裡面,同時,你的max和uninitialized_copy

也需要變成std::max和std::uninitialized_copy

#ifndef GUARD_Vec_h
#define GUARD_Vec_h

#include &
#include &

template & class Vec {

public:
typedef T* iterator;
typedef const T* const_iterator;
typedef size_t size_type;
typedef T value_type;
typedef T reference;
typedef const T const_reference;
typedef std::ptrdiff_t difference_type; //ptrdiff_t &

Vec() { create(); }
explicit Vec(size_type n, const T t = T()) { create(n, t); }

Vec(const Vec v) { create(v.begin(), v.end()); }
Vec operator=(const Vec); // 單獨定義
~Vec() { uncreate(); }

void clear() { uncreate(); }

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& alloc;

void create();
void create(size_type, const T);
void create(const_iterator, const_iterator);

void uncreate();

void grow();
void unchecked_append(const T);
};

template &
Vec& Vec&::operator=(const Vec rhs)
{
if (rhs != this) {
uncreate();
create(rhs.begin(), rhs.end());
}
return *this;
}

template & void Vec&::create()
{
data = avail = limit = 0;
}

template & void Vec&::create(size_type n, const T val)
{
data = alloc.allocate(n);
limit = avail = data + n;
std::uninitialized_fill(data, limit, val);
}

template &
void Vec&::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = std::uninitialized_copy(i, j, data);
}

template & void Vec&::uncreate()
{
if (data) {
iterator it = avail;
while (it != data)
alloc.destroy(--it);

alloc.deallocate(data, limit - data);
}
data = limit = avail = 0;
}

template & void Vec&::grow()
{
//when growing, allocate twice as much space as currently in use
size_type new_size = std::max(2 * (limit - data), ptrdiff_t(2));

iterator new_data = alloc.allocate(new_size);
iterator new_avail = std::uninitialized_copy(data, avail, new_data);

uncreate();

data = new_data;
avail = new_avail;
limit = data + new_size;
}

template & void Vec&::unchecked_append(const T val)
{
alloc.construct(avail++, val);
}
#endif


詳細請參考《C++ Template》6.1.1 對鏈接錯誤的解釋

這個是模板的常見錯誤,模板實現放在了源文件里,頭文件只是定義。會導致鏈接錯誤。

編譯器需要指定特定的類型來初始化,編譯器找不到真正的實例化對象。

《C++ Template》6.3

解決方案有兩種,顯示實例化 (直接使用template關鍵字和類型實例模板原型直接在頭文件寫好) 包含模型(直接在源碼中包含模板函數的實現的源碼文件,直接include cpp文件)

舊的標準(03)為此還進入了關鍵字export (《C++ Template》6.4)來解決這個問題,不過沒有人用這個關鍵字。

詳細的說明可以參考上面的章節的說明。


太長了懶得看

買本C++Primer卡,別瞎寫


不是新手么, 怎麼還上模板了, 這還讓不讓我們這些屌絲活了


模板的分別編譯在大多數編譯器上都沒有實現。


推薦閱讀:

VS2017安裝過程出錯怎麼辦?
如何單獨提取出MSVC2017編譯器並在其他IDE使用?
這段程序的內存泄漏在哪?
微軟是不是要放棄 VB 了?

TAG:編程 | MicrosoftVisualStudio | CC |