C++LNK2019錯誤如何解決?

這是我寫的封裝,有一個取得數組長度的方法。

#include "zufmh.h"

using namespace cua;

using namespace std;

int main(){

// 測試取數組長度

int arr[5];

cout&<&Sleep(5000);

}

這是測試程序,下面的是封裝頭文件:

#ifndef _ZUFMH_H_

#define _ZUFMH_H_

#include & //常用頭文件引用

#include &

#include &

#include &

#include &

#include &

//常用演算法類

namespace cua{

class cuac{

public:

static int isPrimes(float num); //判斷質數

static int isPrimes(double num);

static int isPrimes(long double num);

template &

static int getArrayLen(T array); //應該是這行有問題

static void ArrSort(int *arr[]);//數組排序int

static void ArrSort(short int *arr[]);//數組排序short int

static void ArrSort(long int *arr[]);//數組排序long int

static void ArrSort(float *arr[]);//數組排序float

static void ArrSort(double *arr[]);//數組排序double

};

}

#endif

然後,下面是實現源程序:

#include "zufmh.h"

using namespace cua;

int cuac::isPrimes(float num){

register float sqr=sqrt((float)num);

for(register int i=2;i&<(int)sqr+1;++i) if((int)num%i==0) return 0;

return 1;

}

int cuac::isPrimes(double num){

register float sqr=sqrt((float)num);

for(register int i=2;i&<(int)sqr+1;++i) if((int)num%i==0) return 0;

return 1;

}

int cuac::isPrimes(long double num){

register float sqr=sqrt((float)num);

for(register int i=2;i&<(int)sqr+1;++i) if((int)num%i==0) return 0;

return 1;

}

void ArrSort(int *arr[]){

register int len=cuac::getArrayLen(arr);

for(register int i=0;i&for(register int j=0;j&

}

}

}

template &

int cuac::getArrayLen(T array){

return (sizeof(array) / sizeof(array[0]));

}

還有錯誤信息是:

1&>------ 已啟動生成: 項目: zufmh, 配置: Debug Win32 ------

1&>生成啟動時間為 2014-03-08 20:10:41。

1&>InitializeBuildStatus:

1&> 正在對「Debugzufmh.unsuccessfulbuild」執行 Touch 任務。

1&>ClCompile:

1&> testhzuf.cpp

1&>testhzuf.obj : error LNK2019: 無法解析的外部符號 "public: static int __cdecl cua::cuac::getArrayLen&(int ()[5])" (??$getArrayLen@$$BY04H@cuac@cua@@SAHAAY04H@Z),該符號在函數 _main 中被引用

1&>C:programsC++ est1Debugzufmh.exe : fatal error LNK1120: 1 個無法解析的外部命令

1&>

1&>生成失敗。

1&>

1&>已用時間 00:00:03.20

========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========

有什麼辦法嗎?


應該是你的編譯器不支持模板分離編譯


多次遇見與題主一模一樣的問題,經過查證和實踐,已確認解決!

這裡面的問題是這樣的。

假如你寫了一個類模板,比如這樣:

template&
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo& f;

當程序需要實例化這個類模板的時候,它會根據給定的參數創建一個新類(我們不妨叫它

FooInt),它與下面的定義等價:

struct FooInt
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}

創建了這個類之後,編譯器需要根據給定的參數(此處為int)實現類方法,但如果類方法的實現不在頭文件中,編譯器無法訪問,那麼這個類(FooInt)的實例化就會失敗。這也就是VS報LNK2019錯誤的原因,那個「無法解析的外部符號」就是指編譯器在頭文件中找不到類方法的實現。

最最樸素的方法是把所有的模板類方法的實現也放在頭文件.h當中,但顯然這非常的丑,和我們習慣的.h文件放類定義/.cpp文件放類方法實現的做法相悖。下面給出兩種解決方案,依然保持這兩個文件的分離,但是可以解決編譯報錯的問題:

1. 把類的實現放在一個.tpp文件中,然後在頭文件的最後include這個.tpp文件

// Foo.h
template &
struct Foo
{
void doSomething(T param);
};

#include "Foo.tpp"

// Foo.tpp
template &
void Foo&::doSomething(T param)
{
//implementation
}

這樣,當編譯器要實例化這個FooInt類的時候,可以訪問.tpp文件中的實現

2. 依然是通常的.h/.cpp文件,而在頭文件的最後顯式地實例化你可能用到的模板實例

// Foo.h

// no implementation
template & struct Foo { ... };

//----------------------------------------
// Foo.cpp

// implementation of Foo"s methods

// explicit instantiations
template class Foo&;
template class Foo&;
// You will only be able to use Foo with int or float

這種方式比上一種方式的優勢在於,一旦你把文件名改成.tpp,很多編輯器/IDE的語法高亮會失效,看著巨丑(當然劣勢就在於限定了所有可能的參數類型,對於使用者而言,要使用自定義類實例化這個類模板會有困難。

更詳盡的討論可以見: C++ Super-FAQ on this subject

註:

事實上,在《The C++ Standard Library: A Tutorial and Reference》這本書當中,作者認為:"The only portable way of using templates at the moment is to implement them in header files by using inline functions.",不過就目前的情況而言,顯然把他們丟在一個文件里不再是only的選擇了。

當然此處腳註也指出:「To avoid the problem of templates having to be present in header files, the standard introduced a template compilation model with the keyword export. However, I have not seen it implemented yet.」 我對新標準的實現也不熟悉,因此如果有人清楚的話也請在評論區指出。

參考:

http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file


模板沒有全特化的實現還是不要放在源文件里吧,如果是全特化的話吧對應源文件編譯出來的鏈接進去吧


模板的實現放頭文件裡面吧,STL全部是頭文件。


推薦閱讀:

對於 C++ 的疑惑?
vs2010 程序退出的時候崩潰地方,不知道如何解決?
C++多線程環境下里如何精確獲取shared_ptr的引用計數?
如何評價Andrei Alexandrescu提出的c++ policy-based design?
為什麼libstdc++的allocator要實現兩個operator==?

TAG:C | MicrosoftVisualStudio2010 |