3

これに相当する Visual Studio 2012 プロジェクトがあります。

Header.h

template< class T >
inline int Demonstrate( const char *txt, T *input )
{
  return printf("%s %d %f\n", txt, input->Integer(), input->Real() );
}

ソース.cpp

#include "Header.h"

class Foo 
{
public:
   int Integer() { return 2; }
   float Real() { return 3.14159f; }
};

int main()
{
   Foo example;
   printf( "%d\n", Demonstrate( "foo:", &example ) );
   return 0;
}

しかし、コンパイルすると、LNK2019 エラーが発生します。

unresolved external symbol "int __cdecl Demonstrate(char const *,class Foo *)"

通常、これはテンプレート化された関数がヘッダーで宣言され、cpp でのみ定義されている場合に発生しますが、ここではそうではありません。関数はヘッダーでインラインで定義されます。

何が原因で、どうすれば修正できますか?

編集

これは、ヘッダーを完全に削除して、Demonstrate() を Source.cpp の先頭に貼り付けただけでも発生します。プロジェクトのプロパティの「インライン関数展開」が「デフォルト」または「.」に設定されている場合に発生し"/Ob2"ます。これはプロジェクト設定の一部に違いありませんが、何ですか?

4

2 に答える 2

2

これを追跡したところ、ジョエルが正しい道を進んでいたことがわかりました。関数 Demonstrate() は、複数のヘッダーで複数回プロトタイプ化されていました — 非常にわかりにくい方法で。明示的なint Demonstrate( const char *txt, Foo *input )宣言がありました。これをテンプレートに置き換えました。

しかし、これに似たものが散らばっている他のいくつかのヘッダーがありました (実際の関数とクラスの名前ははるかに複雑であると推測できます)。

header a.h:

#define FUNC_PREFIX Demo

header b.h:

#define REGISTER_CLASS( retype, classname, FUNC_SUFFIX ) retype FUNC_PREFIX ## FUNC_SUFFIX ( const char *txt, classname *ptr )

header c.h:

REGISTER_CLASS( int, Foo, nstrate );
REGISTER_CLASS( int, Bar, nstrate );
// etc

これから何を引き出すべきかわかりません。一方では、これは非常に特定のコードベースに対する非常に特定のバグであり、ローカライズされすぎて有用な SO の質問にはなりません。一方、ここには教えるべき瞬間があります。

卑劣な方法でグローバル関数を定義するためにマクロを使用しないでください

さもなければ、私のような貧弱な樹液は、このような問題を追跡するのに何時間も費やします.

于 2013-08-06T03:46:44.163 に答える
1

テンプレートの自動特殊化に頼れない場合があります。以前にVSでこれに遭遇したことがあり、最終的に明示する必要がありました。 すなわち

Demonstrate<Foo>("foo:", &example)
于 2013-08-06T02:04:34.627 に答える