这是my previous question的延续。
我正在尝试使用嵌套类模板创建一个类模板,其中嵌套类模板具有静态函数,我想为其提供特化。
这是我的测试代码,它没有提供嵌套类的特化。注意空类NullType
的存在 - 这就是我想要专门化嵌套类的原因。
#include <cstdlib>
#include <iostream>
using namespace std;
class NullType {};
template<class FooParam> struct Foo
{
template<class BarParam> struct Bar
{
static bool Magic();
};
};
template<class FooParam>
template<class BarParam>
bool Foo<FooParam>::Bar<BarParam>::Magic()
{
return true;
}
int main()
{
bool b = Foo<int>::Bar<int>::Magic();
cout << b << " ";
bool b2 = Foo<int>::Bar<NullType>::Magic();
cout << b2 << " ";
}
此代码按预期编译和运行。输出是:
1 1
现在我想在Bar::Magic
上提供NullType
的特化,并让该函数返回false
。所需的输出是:
1 0
所以我试着写这样的专业化:
template<class FooParam>
template<>
bool Foo<FooParam>::Bar<NullType>::Magic()
{
return false;
} // COMPILER ERROR HERE C3855
此定义出现在Foo::Bar::Magic()
的现有定义之前。
但是,此代码会导致编译器错误:
1>.\main.cpp(20) : error C3855: 'Foo<FooParam>::Bar<BarParam>': template parameter 'BarParam' is incompatible with the declaration
......在上面的结束支撑上。
我可以使用什么语法来提供此专业化?我愿意接受任何和所有技术来实现我的主要目标(只要false
返回NullType
,true
返回其他所有内容),只要:
Foo
是一个类模板,Bar
是嵌套类模板或函数模板。返回false
或true
的函数必须是特殊的或可重载的,以便调用NullType
的代码返回false
,但其他所有内容都将返回true
}。如果需要,我会澄清要求。
答案 0 :(得分:2)
如@Ise Wisteria的评论所述,C ++ 03和C ++ 11都禁止对其封闭类进行专门化的嵌套类/方法的专门化。
以下使用重载的解决方案是否适用于您?
#include <cstdlib>
#include <iostream>
using namespace std;
class NullType {};
template<class FooParam> struct Foo
{
template<class BarParam> static bool Magic(BarParam);
static bool Magic(NullType);
};
template<class FooParam>
template<class BarParam>
bool Foo<FooParam>::Magic(BarParam)
{
return true;
}
template<class FooParam>
bool Foo<FooParam>::Magic(NullType)
{
return false;
}
int main()
{
bool b = Foo<int>::Magic(int());
cout << b << " ";
bool b2 = Foo<int>::Magic(NullType());
cout << b2 << " ";
}
答案 1 :(得分:2)
另一种替代变体是使用非嵌套特征类:
class NullType {};
template<class FooParam> struct Foo
{
template<class BarParam> struct Bar
{
static bool Magic();
};
};
template<class T> struct bool_trait
{
static const bool value = true;
};
template<> struct bool_trait<NullType>
{
static const bool value = false;
};
template<class FooParam>
template<class BarParam>
bool Foo<FooParam>::Bar<BarParam>::Magic()
{
return bool_trait<BarParam>::value;
}
答案 2 :(得分:1)
快速解决方案是使用typeid运算符,它是标准C ++(5.2.8)。所以你的Magic()函数如下所示:
template<class FooParam>
template<class BarParam>
bool Foo<FooParam>::Bar<BarParam>::Magic()
{
if (typeid(BarParam) == typeid(NullType))
return false;
return true;
}
据我所知,编译器在typeid和typeinfo的实际实现中有一些自由,但是==运算符可以保证像你期望的那样工作。需要注意的是,显然有些编译器默认不支持运行时类型信息以提高性能;大多数应该有一个标志来打开它。