2010-11-24 29 views
1

私はこの美しさを書きました。しかし、私がコンパイルすると、MSVCはmake_literal関数が定義されていない外部関数であると言います。未解決の外部エラー

編集:私はすべてのテンプレートの塊なしで問題を減らすことができました。

struct some { 
    friend int main(); 
private: 
    static wchar_t hidden[40]; 
public: 
    some() 
    {  
    } 
}; 

int main() { 
    std::cout << some::hidden; 
    //const wchar_t* lit = make_literal<sizeof(something::ref), something::ref, wchar_t>(); 
} 
main.obj : error LNK2001: unresolved external symbol "private: static wchar_t * some::hidden" ([email protected]@@0PA_WA) 

静的な配列です。人生は私を憎むのだろうか?

+0

。このコードは、華麗または狂気のいずれかです –

+0

これは文字列リテラルへの参照です。 – Puppy

+0

"..この美しさ" - 美容の完璧な例 "美しさは見る人の目にある" :) –

答えて

2

問題は、to_literal::hiddenが宣言されていますが、定義されていないということです。別のを見てみましょう:

struct something { 
    static const char ref[]; // declaration of something::ref 
}; 

const char something::ref[] = ""; // definition of something::ref 

template<int N, const char(&t_ref)[N], typename to> struct to_literal { 
private: 
    static to hidden[N]; // declaration of to_literal::hidden (but there's no 
          // definition anywhere) 
public: 
    to_literal() 
    : ref(hidden) { 
     for(int i = 0; i < N; i++) 
      hidden[i] = t_ref[i]; 
    } 
    const to(&ref)[N]; 
}; 

はこれを修正するには、to_literal::hiddenの適切な定義を追加します。私はまだ何 `のconstのchar(参考文献)[N]`手段を把握しようとしている

template<int N, const char(&t_ref)[N], typename to> 
to to_literal<N, t_ref, to>::hidden[N]; // definition of to_literal::hidden 
+0

共有メンバーはテンプレート引数からのみコピーされるため、安全ではないとは思いません。異なるスレッドから複数のto_literalインスタンスを作成したとしても、同じ値を割り当てるだけです。値がすべて同じであるため、どのスレッドが最初に行くか、どのスレッドのどのビューがあるかは関係ありません。また何らかの理由でMSVC10はその定義を拒否し、テンプレートの引数が順不同であると言います。 – Puppy

+0

@DeadMG:あなたはそれについてもっと考えた後、マルチスレッドの部分について正しいですよ。異なる引数を持つ複数のスレッドから 'make_literal'を呼び出した場合に起こることについて考えていましたが、それらが異なる引数を持つ場合、異なるテンプレートインスタンスを参照するため、すべてが良好です。議論が同じであれば、レースがあるが、誰が勝つかは問題ではない。 MSVC10がこれを拒否する理由は考えられません。 g ++は '-Wall -Wextra -pedantic'でも何も与えません。 –

+0

私はMSVC10がこれを拒否する理由を理解できません。私はMSDNの特定のエラーをチェックし、私は間違いなく間違いを犯さなかった。 – Puppy

1

VC 2008でこれを構築したとき、それは私が得たエラーではありませんでした。エラー:

エラー1つのエラーLNK2001:未解決の 外部シンボル「プライベート:静的 はwchar_t * to_literal < 1、&公共::: refを、wchar_t型>静的 のcharのconst * constの 何か::隠さ「 問題を解決しto hidden[N];メンバーからstaticを削除MAIN.OBJイネーブラ

(?@?$ to_literal隠さ@@ 2QBDB_W @@ 0PA_WA何か@ $ 00 $ 1→REF @)。

エラーメッセージは正しいですか?

+0

@OJ:エラーメッセージを誤解しました。静的修飾子を削除することはできません。それは単なる静的配列なので、問題の内容を理解できません。 – Puppy

+0

私は私が言ったことが十分にはっきりしていなかったと思います。静的メソッドを削除すると、実際には 'hidden'メンバのインスタンスが定義されます(本当に問題があったはずです)。もう1つの選択肢は、アダムが推奨したものを外部に定義することです。 –

2

静的メンバーは宣言していますが、定義していません。コンパイラはを訴え...

template<int N, const char(&t_ref)[N], typename to> 
to to_literal<N, t_ref, to>::hidden[N]; 

...私はあまりにもあなたのためにMSVCでチェックしようとしたが、VS2005で、私は別の愚かなエラーが出る...のような

template<int N, const char(&t_ref)[N], typename to> 
to to_literal<N, t_ref, to>::hidden[N]; 

を何かを追加...

error C3860: template argument list following class template name must list parameters in the order used in template parameter list 

1つのバグを修正したときのように見えますが、後ろにもう1つあります。

+0

私はそれを試しました。どうやら、クラステンプレートの引数リストは誤って形成されています(配列指定子を追加することを思い出しました)。 – Puppy

+0

それはうまくいかない - あなたが話している特定のテンプレートのインスタンス化のための静的メンバーを定義する必要があります。テンプレートは実際に何も作成していないことを覚えておいてください。テンプレートは何かを作成する方法を定義するだけです。 –

+0

@Drew Hall:クラス内のメンバー関数を定義したのと同じように、気になる可能性があるすべてのインスタンス化に対して定義しています。テンプレートを特殊化しない限り、すべてのインスタンス化でインスタンス化されると思います。 – Puppy

2

静的メンバーを定義する場合、宣言では不十分です。 You must provide a definition outside the class。私。追加します。

wchar_t some::hidden[40]; 

クラス外に追加して定義します。

それ以外の場合、C++でこれが許可されていれば、ヘッダーにグローバル変数を定義するのと同じ問題が発生します - それを含む.cppファイルごとに重複した定義が付きます。多重定義されたシンボルエラー。

関連する問題