2012-03-30 4 views
1

を働いていないテンプレート次のプロジェクトがコンパイルされると、私は次のコンパイラエラーを取得:(Visual Studioの2010)C++:他のクラスから

1> usingclass.obj:エラーLNK2019:未解決の外部シンボル「パブリック:静的関数 "public:void __thiscall usingclass :: a(void)"で参照されるint __cdecl c1 :: arrSize(int * const) "(?? $ arrSize @ H @ c1 @@ SAHQAH @ Z) QAEXXZ)

コード:

ヘッダ:

c1.h

#pragma once 
#include <array> 
class c1 
{ 
    c1(void); 
    ~c1(void); 
public: 
    template<class T> 
    static int arrSize(T arr[]); 
}; 

usingclass.h

#pragma once 
#include "c1.h" 

class usingclass 
{ 
public: 
    usingclass(void); 
    ~usingclass(void); 
    void a(); 
}; 

ソースファイル:

c1.cpp

#include "c1.h" 

c1::c1(void) 
{ 
} 


c1::~c1(void) 
{ 
} 

template <class T> 
int c1::arrSize(T arr[]) 
{ 
    return (sizeof(arr)/sizeof(arr[0])); 
} 

usingclass.cpp

#include "usingclass.h" 

usingclass::usingclass(void) 
{ 
} 


usingclass::~usingclass(void) 
{ 
} 

void usingclass::a() 
{ 
    int a[2] = {1,2}; 
    int b = c1::arrSize<int>(a); 
} 

どうすれば修正できますか?

+0

質問には誤解があります。クラスと翻訳単位(コンパイルされたファイル)は直交する概念です。あなたの質問は、別のクラスではなく、別のファイルで定義されたテンプレートを使用することです。 –

答えて

2

あなたはc1.h

template <class T> 
int c1::arrSize(T arr[]) 
{ 
    return (sizeof(arr)/sizeof(arr[0])); 
} 

を移動する必要があります。

テンプレートの実装は、そのテンプレートを使用するすべての翻訳単位で表示する必要があります(特殊化されている場合を除き、そうでない場合)。

これはコンパイラエラーを解決しますが、基本的な問題はVaughn Catoの解答で解決されます。私は逃しました。それでもヘッダーに定義が必要です。

+0

基本的に、私がテンプレートを使用すると、その関数をヘッダファイルに入れる必要がありますか? – NBcode

+0

@NBcodeはい、それはあなたが生きなければならない制約です。 –

7

しないでください!宣言は誤解を招く。

template <class T> 
int c1::arrSize(T arr[]) 
{ 
    return (sizeof(arr)/sizeof(arr[0])); 
} 

は、あなたが欲しい欲しい与えることはありません

template <class T> 
int c1::arrSize(T *arr) 
{ 
    return (sizeof(arr)/sizeof(arr[0])); 
} 

に相当します。それを行うための適切な方法は、このようなものです:

class c1 
{ 
    c1(void); 
    ~c1(void); 
public: 
    template<class T,int N> 
    static int arrSize(T (&arr)[N]) { return N; } 
}; 

arrSizeパラメータとして配列への参照を取ります。配列の型と配列のサイズはテンプレートパラメータであり、コンパイラによって導き出すことができます。インラインメンバ関数は、コンパイラによって決定されたサイズを返します。

+0

+1、関数は単純に壊れています。 –

+0

+1また、定義はヘッダーにあるか、または翻訳単位に表示される必要があります。 –

+0

私はその機能を見ましたが、どういう仕組みが本当に理解できませんでした... – NBcode

0

あなたはテンプレートをc1.h自体に定義する必要があると思います。なぜなら、あなたのusingclass.hにc1.hを含めて、テンプレートを使用しようとすると、テンプレートの展開が見つからないからです。

または、c1.cppでテンプレートの実装を行う場合は、using.hにc1.cppも含める必要があります。

関連する問題