次のプログラムは正常に動作します。静的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.
実際に使用されている特殊化の定義のみを提供するだけでは不十分だと思います。 static
constexpr
のメンバーがclass
の定義の中で初期化されなければならないので、それはあまり役に立ちませんので、私はそれをその定義に特化することはできませんが、未定義のままにしておきたいことがあります。簡単
明示的な特殊化は、主テンプレートの宣言/定義を効果的に置き換えます。 –
@ T.C。私は静的なデータメンバのクラス内の初期化は定義ではないという前提にありました。テンプレート本体の宣言+初期化は、データメンバのすべてのspecilizations-for-implicit-instantiations-of-class-templateに適用されるべきではありませんか? –
@ T.C。はい、私の直感は正しいです:http://coliru.stacked-crooked.com/a/597464c14d48071f。したがって、彼は、初期化子を提供せずに、専門化を宣言するだけなので、定義専門化を提供できないという問題があります。しかし、彼が後者をするなら、彼は2つのイニシャライザを持つでしょう。 –