2015-09-06 2 views
10

MSVCとGCC(おそらくあまりにも)同じコードのコンパイルとリンクの間の不整合の私の発見の後、私はこのプログラムが実際にコンパイルし、リンクし、MSVC(これはリンカーエラーを報告する)それとも別の方法で書かなければならないのですか?プログラムは3つのファイルで構成されています次のプログラムは標準に従ってコンパイルする必要がありますか?

Chの

template <typename T> 
struct A 
{ 
    void func() {}; 
}; 

template <> 
void A<int>::func(); 

A.cpp:

#include "C.h" 
int main() 
{ 
    A<int> x; 
    x.func(); 
} 

B.cpp:

#include "C.h" 
template <> 
void A<int>::func() 
{ 
} 

MSVCから結果のリンカエラーがある:

A.OBJ:エラーLNK2019:未解決の外部シンボル「パブリック:__thiscall :: funcを(ボイド)無効」

だから基本的にはB.cppに配置された定義からシンボルを作成しないことを決定。私がバグとして強く疑っているのは、構造体定義からfuncという特殊化されていない定義を移動し、それを特殊化宣言の上に置くことさえプログラムのインライン化を成功させるということですが、私は確信しています。

私の質問は - このプログラムをコンパイルし、適合するコンパイラ/リンカによってエラーなしでリンクする必要がありますか?規格から

+0

私にはバグのようです。 MSVCの最新バージョン(2015)を使用していますか? –

+0

@MatsPeterssonはい、2015. – Predelnik

+0

あなたのコードはclang ++でもうまくコンパイルされます。あなたが本質的に 'func'の2つの定義を提供しているので、私はちょっと変わっています - 正しいかどうかは言語弁護士では不十分です(私はそうだと思います) –

答えて

1

:インスタンスの

©ISO/IEC N4527 14.6.4.1ポイント[temp.point] 1関数テンプレート特殊化、メンバ関数テンプレートの特殊化、またはのため 専門についてクラス テンプレートのメンバ関数または静的データメンバであり、 が別のテンプレート特殊化内から参照されているために特殊化が暗黙的にインスタンス化され、参照される コンテキストがテンプレートパラメータによって異なります。 専門化はpoiです のntは包囲特化のインスタンス化です。 そうでなければ、 の特殊化のインスタンス化は、 特殊化を参照する 名前空間スコープ宣言または定義の直後に続きます。この場合

私はこれは「スコープ宣言」が発生C.hで意味だと思い。この場合、コードは標準準拠のツールチェーンとリンクする必要があります。私はこれを誤解する可能性があります...

-2

無名の名前空間には内部リンケージがあります。テンプレートの特殊化は名前のない名前空間内にあるため、内部結合もあります。

問題を解決するには、テンプレートを名前付き名前空間に配置するか、特殊化を「extern」として指定します。

+0

"名前のない名前空間"は、あなたが考えると思われるものを意味するものではありません。 –

関連する問題