2016-05-01 5 views
0

次のプログラムは正常に動作します。静的constexprデータメンバーを特定のスペシャライゼーションに対してのみ定義できますか?

#include <iostream> 
#include <type_traits> 

template <typename DummyT = void> 
struct wrapper 
{ 
    static_assert(std::is_same<void, DummyT>::value, "Only void, please"); 
    static constexpr char text[] = "some string constant"; 
}; 

template <typename DummyT> 
constexpr char wrapper<DummyT>::text[]; 

int 
main() 
{ 
    std::cout << wrapper<>::text << '\n'; 
} 

私はwrapper<void>ためwrapper::text

template <> 
constexpr char wrapper<void>::text[]; 

を定義するときしかし、その後、GCC 5.3.0は、私にこのリンカエラー

/tmp/ccnGx3EP.o: In function `main': 
main.cxx:(.text+0x5): undefined reference to `wrapper<void>::text' 
collect2: error: ld returned 1 exit status 

を与え、クラン3.7.1は私に、このエラーが発生します。

main.cxx:12:31: error: declaration of constexpr static data member 'text' requires an initializer 
constexpr char wrapper<void>::text[]; 
          ^
1 error generated. 

実際に使用されている特殊化の定義のみを提供するだけでは不十分だと思います。 staticconstexprのメンバーがclassの定義の中で初期化されなければならないので、それはあまり役に立ちませんので、私はそれをその定義に特化することはできませんが、未定義のままにしておきたいことがあります。簡単

+2

明示的な特殊化は、主テンプレートの宣言/定義を効果的に置き換えます。 –

+0

@ T.C。私は静的なデータメンバのクラス内の初期化は定義ではないという前提にありました。テンプレート本体の宣言+初期化は、データメンバのすべてのspecilizations-for-implicit-instantiations-of-class-templateに適用されるべきではありませんか? –

+0

@ T.C。はい、私の直感は正しいです:http://coliru.stacked-crooked.com/a/597464c14d48071f。したがって、彼は、初期化子を提供せずに、専門化を宣言するだけなので、定義専門化を提供できないという問題があります。しかし、彼が後者をするなら、彼は2つのイニシャライザを持つでしょう。 –

答えて

0

:他のパラメータはstatic_assertで失敗する一方

template <typename DummyT = void> 
struct wrapper 
{ 
    static_assert(std::is_same<void, DummyT>::value, "Only void, please"); 
}; 

template <> 
struct wrapper<void> 
{ 
    static constexpr char text[] = "some string constant"; 
}; 

constexpr char wrapper<void>::text[]; 

両方wrapper<>wrapper<void>が動作します。

+0

これは素晴らしいトリックですが、残念なことに、複数の翻訳単位に '#include'して一緒にリンクしたときに多重定義エラーが発生し、テンプレートの使用目的が曖昧になります「まず第一に、 – 5gon12eder

+0

"constexpr char wrapper :: text [];"という行が複数ある場合は、ヘッダーではなくcppファイルに移動されます。これは、コンパイルで使用されるcppファイル(おそらく、2つのコード行のみを含む独自のcppファイルを含むことができます)(#include文と定義自体) - 静的メンバーを提供する必要がある場合、後者のアプローチを何度も個人的に使用しましたテンプレートクラスの定義。 – Smeeheey

関連する問題