这个问题与a previous Q&A有关,其中提到了gcc的错误报告(据说已在gcc 4.5.0中修复),并涉及嵌套类模板的部分特化的一些特殊性。
我的设置是,我有一个带有嵌套类模板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
}
第二个问题:为什么
Base::Inner<int>::value
等于false
,即使仅Derived::Inner<int>
是部分专用的?Online example using gcc 4.8.0。我正在特别寻找标准中解释这种行为的报价。
最佳答案
局部特化必须重新声明与其提供替代定义的主要模板相同的名称。
当您在struct Inner
范围内编写Derived
时,就是在声明Derived::Inner
。 Base::Inner
是与Derived::Inner
不同的名称,因此声明了一个不同的类。不能使用声明Base::Inner
的声明来专门化Derived::Inner
。
在命名空间范围内编写Derived::Inner
时,名称查找会将其名称解析为Base::Inner
-特化都是同一类:Base::Inner
,即使您将它们称为Derived::Inner
也是如此。
从标准:
关于c++ - 了解继承的嵌套类模板的部分特化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17132753/