给定:
struct A
{
virtual bool what() = 0;
};
template<typename T, typename Q>
struct B : public A
{
virtual bool what();
};
我想部分专门化 what
之类的:
template<typename T, typename Q>
bool B<T, Q>::what()
{
return true;
}
template<typename Q>
bool B<float, Q>::what()
{
return false;
}
但这似乎是不可能的(在 C++11 中?)所以我尝试了 SFINAE:
template<typename T>
typename std::enable_if<std::is_same<T, float>::value, bool>::type B<T>::what()
{
return true;
}
template<typename T>
typename std::enable_if<!std::is_same<T, float>::value, bool>::type B<T>::what()
{
return false;
}
这也不起作用,我不知道为什么,有人吗?于是我找到了this thread最后得到:
template<typename T, typename Q>
struct B : public A
{
virtual bool what()
{
return whatimpl(std::is_same<T, float>());
}
bool whatimpl(std::false_type)
{
return false;
}
bool whatimpl(std::true_type)
{
return true;
}
};
这个最终解决方案有效,但为什么 enable_if
技术无效?我也非常愿意接受我尚未遇到的更简洁答案的建议。
我尽可能简化了我的示例 - 在我的实际用例中,what()
不称为 what,实际上做了很多工作,而且我'会想要'专门化'用户定义的类型,而不是 float
。
最佳答案
标准明确允许部分特化仅用于类模板(请参阅 14.5.5 类模板部分特化)
对于类模板的成员,只允许显式特化。
14.7 (3) 说:
可以为函数模板、类模板、类的成员声明显式特化 模板 或成员模板。 template<> 引入了显式的特化声明。
所以任何以
开头的定义template<typename T>
对于类模板特化的成员不允许使用语法。
[编辑]
关于 SFINAE 的尝试,它失败了,因为实际上这里既没有重载也没有特化(SFINAE 在为重载解决方案定义一组候选函数或选择适当的特化时工作)。 what() 被声明为类模板的单个方法并且应该有一个定义,并且这个定义应该有一个形式:
template<typename T, typename Q>
B<T,Q>:: bool what(){...}
或者也可以明确地专门用于 B 类的特定实例化:
template<>
B<SomeParticularTypeT,SomeParticularTypeTypeQ>:: bool what(){...}
任何其他形式在语法上都是无效的,所以 SFINAE 无能为力。
关于c++ - 模板类中方法的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10284498/