この質問は、gcc のバグ レポート (gcc 4.5.0 で修正されたと思われる) が言及された以前の Q&Aに関連しており、ネストされたクラス テンプレートの部分的な特殊化に関するいくつかの特殊性に関係しています。
私のセットアップは、部分的に特化Base
されたネストされたクラス テンプレートを持つクラスがあることです(クラス内で明示的な仕様が許可されていないため、ダミー パラメーター トリックを使用します)。Inner
char
#include <type_traits>
#include <iostream>
#include <ios>
struct Base
{
// dummy template parameter...
template<class U, class _ = void> struct Inner: std::true_type {};
// ... to allow in-class partial specialization
template<class _> struct Inner<char, _>: std::false_type {};
};
Derived
ここで、さらに特化したいクラスを定義しますがInner
、これは何らかの奇妙な理由でクラス内で行うことができません (まだ部分的な特化であるにもかかわらず)。
struct Derived
:
Base
{
// cannot partially specialize Inner inside Derived...
//template<class _>
//struct Inner<int, _>: std::false_type {};
};
// ... but specializing Derived::Inner at namespace scope, also specializes it for Base::Inner
template<class _> struct Derived::Inner<int, _>: std::false_type {};
最初の質問Derived::Inner
:名前空間スコープで部分的に特殊化する必要があるのはなぜですか?
しかし、最も奇妙な部分は、 と のInner
両方のさまざまな部分特殊化を呼び出すBase
と、に対してのみ行っDerived
た部分特殊化がにも適用されることです。int
Derived
Base
int main()
{
std::cout << std::boolalpha << Base::Inner<float>::value << "\n";
std::cout << std::boolalpha << Derived::Inner<float>::value << "\n";
std::cout << std::boolalpha << Base::Inner<char>::value << "\n";
std::cout << std::boolalpha << Derived::Inner<char>::value << "\n";
std::cout << std::boolalpha << Base::Inner<int>::value << "\n"; // huh???
std::cout << std::boolalpha << Derived::Inner<int>::value << "\n"; // OK
}
2 番目の質問: 部分的にしか特殊化されていないのに、なぜ が にBase::Inner<int>::value
等しいのですか?false
Derived::Inner<int>
gcc 4.8.0 を使用したオンラインの例。この動作を説明する標準からの引用を特に探しています。