クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
うにお

クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#1

投稿記事 by うにお » 8年前

初めて利用させて戴きます。
宜しくお願いいたします。

設計の良し悪しはともかく、任意の型の配列に格納された全ての値の平均値を求めるプログラムを書いたのですが、
コンパイルが通らず、原因が調べております。
VC++2010を使用しています。
また、必要なinclude等は省略しています。

コード:

/************
  Helper.h
************/
using namespace std;

class Helper {
	public:
		/** 配列の平均を計算 */
		template < typename T > static T getAverage( const int, T* );
	private:
		/** コンストラクタ(実装禁止) */
		Helper();
		/** デストラクタ(実装禁止) */
		~Helper();
};

コード:

/************
  Helper.cpp
************/
#include "Helper.h"
using namespace std;

template < typename T > T Helper::getAverage( const int dataNum, T *ptr ) {

	T sum = *ptr;
	for( int i = 1; i < dataNum; i++ ) {
		sum += *( ptr + i );
	}
	return sum / dataNum;
}

コード:

/************
  main.cpp
************/
#include "Helper.h"
using namespace std;

int _tmain( int argc, _TCHAR* argv[] ) {
	/** 省略 */

	vector< double > test( 3, 0,5 );
	test.push_back( 0.3 );
	test.push_back( 0.2 );
	test.push_back( 0.1 );

	double ave = Helper::getAverage( test.size(), test.data() );
	cout << "平均: " << ave << endl;
}
これをコンパイルすると、double ave = Helper::getAverage( test.size(), test.data() );のところでエラーとなってしまいます。
Helper::getAverage( const int, T *ptr )を呼び出さない限りはエラーとはなりません。

エラーは2つ出ており、

① error LNK2028: 未解決のトークン (0A0001A8) "public: static double __cdecl Helper::getAverage<double>(int,double *)" (??$getAverage@N@Helper@@$$FSANHPAN@Z) が関数 "int __cdecl wmain(int,wchar_t * * const)" (?wmain@@$$HYAHHQAPA_W@Z) で参照されました。
② error LNK2019: 未解決の外部シンボル "public: static double __cdecl Helper::getAverage<double>(int,double *)" (??$getAverage@N@Helper@@$$FSANHPAN@Z) が関数 "int __cdecl wmain(int,wchar_t * * const)" (?wmain@@$$HYAHHQAPA_W@Z) で参照されました。

というものです。
また、呼び出し方を変え、Helper::getAverage< double >( const int, T *ptr )とやってみましたがダメでした。

テンプレート関数の戻り値とポインタ引数に原因があるのではと睨んでいるのですが…。
分かる方、ご教授頂けると幸いです。
宜しくお願いいたします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#2

投稿記事 by h2so5 » 8年前

テンプレート関数の実装はヘッダ側に書いてください。

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

Re: クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#3

投稿記事 by Aozora0630 » 8年前

ソース見てまんま答えを言うのは面倒くさいし、自分だったらためにならないのでそのエラーが出るケースだけ書いておきます。

未解決の外部シンボル~~~
これは、プロトタイプ宣言されたにもかかわらず本体が書かれていない関数があると発生するエラーです。
因みに、宣言した関数を呼ばない限りこのエラーは出ません。
つまり、呼び出した関数の本体が無いってことです。
私はよく、スコープが複雑になるとこんなミスをします。


トークンが何たらかんたら
やべえ、初めて見たこのエラー
其れはさて置き、トークンはコンパイラが言語を機械語に変換する時、関数名や、変数名を分けるためにトークンという単位に分けます。
例えば→printf("%i",GetValue());→トークン変換→[printf][(]["%i"][,][GetValue][(][)][)];
[]はトークンの分割という意味です。コンパイラがこう認識してるってことです。
そのトークンが未解決ということは、コンパイラが認識不可能ということです。
つまりは、変なところに空白や全角文字とかが入ってるって事じゃないですかね?
私はtempleteとか使わないので、よくわかりませんが、多分そういうことだと思います。
曖昧になってすみません。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#4

投稿記事 by h2so5 » 8年前

Aozora0630 さんが書きました: 因みに、宣言した関数を呼ばない限りこのエラーは出ません。
http://ideone.com/HRzl7u

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

Re: クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#5

投稿記事 by Aozora0630 » 8年前

h2so5 さんが書きました:
Aozora0630 さんが書きました: 因みに、宣言した関数を呼ばない限りこのエラーは出ません。
http://ideone.com/HRzl7u
あ、私はbcc32使ってるのでつい・・・。他は知りませんがエラーなことに代わりはありません。

うにお

Re: クラスメンバのstaticなテンプレート関数の戻り値とポインタ引数について

#6

投稿記事 by うにお » 8年前

h2so5様、Aozora0630様
ご返信ありがとうございます。

ご教授頂きありがとうございました。
ヘッダ側に直接実装を行ったところ、無事にコンパイルが通り、
実行結果も正しいものとなりました。

まだまだひよっこなので、エラーから原因が特定できる点が非常に勉強になりました。
今後ともよろしくお願い申し上げます。

閉鎖

“C言語何でも質問掲示板” へ戻る