2016-01-24 19 views
5

変数テンプレートをヘッダーファイルで宣言してから別のコンパイル単位で実際のインスタンス化を行いたいと思います。テンプレート変数を定義せずに宣言できません

私は、C++ 14の変数テンプレートが静的なクラス変数と非常によく似ていると信じられました。残念ながら、これはかなりの事態ではないようですが、変数テンプレートを宣言するのが妨げられています。

template <typename T> struct Variable { 
    static int variable; 
}; 

template <typename T> 
extern int variable; 

int main() { 
    (void) Variable<char>::variable; 
    // (void) variable<char>;     // <-- line 10 
} 

template <> int Variable<char>::variable = 42; 
template <> int variable<char> = 23; 

上記のコードサンプルは、GCCでそのままコンパイルされ、実行されます。しかし、コメントを解除ライン10は、コンパイル時エラーを与える:

specialization of 'variable<char>' after instantiation 
    template <> int variable<char> = 23; 
        ^
+1

Clangは両方を拒否します。これは不正な形式のNDRです。明示的*インスタンス化*と明示的*特殊化*は全く異なる獣です。 –

+0

すべての権利 - どのように*行う*私は何をしたいのですか?ヘッダー内の変数を宣言しますが、それは.cppで定義します。 –

答えて

1

は、私はあなたが正しい軌道に乗っていると思います。

このトリックはこれです。どの翻訳単位でも、特殊化の前にテンプレートをインスタンス化しないでください。

// test.h 
#ifndef TEST_H 
#define TEST_H 

template <typename T> 
extern int variable; 

template <> extern int variable<char>; 
template <> extern int variable<int>; 

#endif // TEST_H 

その後:

// test2.cpp 
#include "test.h" 

template <> int variable<char> = 23; 
template <> int variable<int> = 24; 

そして最後に:たとえば

私にとって

// test.cpp 
#include "test.h" 
#include <iostream> 

int 
main() 
{ 
    std::cout << variable<char> << '\n'; 
    std::cout << variable<int> << '\n'; 
} 

は、この出力:

23 
24 

更新

T.C.以下のコメントでは、スペシャライゼーションを最初に使用する前に宣言する必要があることを指摘しています。そのために、上記の "test.h"を更新しました。

アップデート2

いくつかの実装の相違があるようです。打ち鳴らすには、この罰金を処理するために表示されます。

template <typename T> 
extern int variable; 

template <> extern int variable<char>; 
template <> extern int variable<int>; 

#include <iostream> 

int 
main() 
{ 
    std::cout << variable<char> << '\n'; 
    std::cout << variable<int> << '\n'; 
} 

template <> int variable<char> = 23; 
template <> int variable<int> = 24; 

http://melpon.org/wandbox/permlink/DGYKvvoPbmRIHaFi

しかしgccがエラーを与える:

prog.cc:4:13: error: explicit template specialization cannot have a storage class 
template <> extern int variable<char>; 
      ^~~~~~ 

prog.cc:5:13: error: explicit template specialization cannot have a storage class 
template <> extern int variable<int>; 
      ^~~~~~ 

私は標準とコアの問題のリストを検索した、と私は見つけることができません1つのコンパイラまたは他のコンパイラが正しいことを示すもの。誰かがそのような証拠を見たら、私はこの答えにそれを含めてうれしいです。

+0

これはまだ[不良なNDR](http://eel.is/c++draft/temp.expl.spec#6)です。必要なのは、ヘッダーの明示的な特殊化の宣言ですが、OPが実際に明示的にテンプレートを特殊化することを意味するかどうかはわかりません。 –

+0

@ T.C .: Thanks、fixed。 –

+0

これはまだ動作しません - ここにコードです。 https://github.com/rec/variable-templateこれはclangではまったく動作しません。 g ++ 5.3.0ではコンパイルされますが、0と0が出力されます。 "統一"ビルドもコンパイルされません。 –

関連する問題