どうやら、MSVC2005はローカルクラスのメンバー関数をインライン化できず、LNK2005につながります。
以下をコンパイルするときに、このLNK2005エラーに直面しています。
common.h
コンテンツ:
inline void wait_what()
{
struct wtf
{
void ffffuuu() {}
} local;
}
foo.cpp
コンテンツ:
#include "common.h"
void foo()
{
wait_what();
}
bar.cpp
コンテンツ:
#include "common.h"
void bar()
{
wait_what();
}
LNK2005.cppコンテンツ:
// forward declarations
void foo();
void bar();
int main()
{
foo();
bar();
return 0;
}
エラーメッセージは次のとおりです。
error LNK2005: "public void __thiscall `void__cdecl wait_what(void)'::`2'::wtf::ffffuuu(void)" (?ffffuuu@wtf?1??wait_what@@YAXXZ@QAEXXZ) already defined in bar.obj
ローカルクラスについて、ISOIEC14882-2003は次のように述べています。
9.8ローカルクラス宣言
クラスは関数定義内で定義できます。このようなクラスはローカルクラスと呼ばれます。ローカルクラスの名前は、それを囲むスコープに対してローカルです。ローカルクラスは、囲んでいるスコープのスコープ内にあり、囲んでいる関数と同じように、関数の外部の名前にアクセスできます。ローカルクラスの宣言では、型名、静的変数、外部変数と関数、および囲んでいるスコープの列挙子のみを使用できます。
囲み関数には、ローカルクラスのメンバーへの特別なアクセス権はありません。通常のアクセスルール(11節)に従います。ローカルクラスのメンバー関数は、定義されている場合は、クラス定義内で定義されるものとします。
私は何か見落としてますか?
私には、コンパイラのバグのように見えます。GCCとMSVC2008はそれをうまくコンパイルします。ただし、実際にコールをインライン化するのか、リンクフェーズ中に2つのシンボルの1つを破棄するだけなのか疑問に思います。興味深いことに、このローカルクラスメンバー関数への呼び出しさえないことに気付くでしょう。
MSVC2005の回避策があるかどうか疑問に思います。私はMSDNでこの典型的な問題を検索しようとしましたが、あまり成功しませんでした。コンパイラの既知のバグのリストを見つけることさえできませんでした。
添付ファイル:LNK2005.zip