模板化类中方法的部分专用化
Partial specialization of a method in a templated class
给定:
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;
}
这也行不通,我不知道为什么,有人吗?所以我找到了这个线程并最终得到:
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()
不被称为什么,实际上做了相当多的工作,我想"专注于"用户定义的类型,而不是float
。
标准明确允许部分专用化仅适用于类模板(请参阅 14.5.5 类模板部分专用化)
对于类模板的成员,只允许显式专用化。
14.7 (3) 说:
可以为函数模板、类模板、类的成员声明显式专用化模板或成员模板。模板<>引入了显式专用化声明。
所以任何以
template<typename T>
不是类模板专用化成员允许的语法。
[编辑]
至于 SFINAE尝试,它失败了,因为实际上这里既没有重载也没有特化(SFINAE 在定义一组用于重载解析的候选函数或选择适当的特化时工作)。 what() 被声明为类模板的单个方法,并且应该有一个定义,并且这个定义应该有一个形式:
template<typename T, typename Q>
B<T,Q>:: bool what(){...}
或者也可以明确地专门用于类 B 的特定实例化:
template<>
B<SomeParticularTypeT,SomeParticularTypeTypeQ>:: bool what(){...}
任何其他形式在语法上都是无效的,所以SFINAE无能为力。
为什么不把它改成..
template<typename T, typename Q>
struct B : public A
{
bool what()
{
return false; //Or whatever the default is...
}
};
template<typename Q>
struct B<float, Q> : public A
{
bool what()
{
return true;
}
};
两种可能的解决方案,具体取决于您的用例:
- 灵活的实现类:您的方法的一个问题是类型缺乏灵活性 - 不超过 true 或 false 类型。基于这个出色的 CppCon 演讲(幻灯片 77),我通过将工作委托给另一个特定于实现的类模板来编写此解决方案。您可以在此处查看并运行此代码。此方法的缺点是我无法访问其余的类成员,但可以传入它们。
- 操作启用如果:我还没有完全理解为什么您的enable_if解决方案不起作用,但这是我的,它正在工作。它允许您在类本身内部分专攻。
附言我正在尝试直接在此处添加代码,但存在一些格式问题。如果有人可以帮助我添加来自 Coliru 的格式化代码,那就太好了。
相关文章:
- 检查子类型时的专用方法模板
- 部分方法专用化
- 基于枚举参数调用专用模板方法
- 类中一种方法的部分专用化
- 从非模板类调用专用模板方法
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 没有针对完全专用模板类的外联虚拟方法定义
- 从部分专用模板方法调用模板非静态方法
- 添加具有模板专用化的方法
- 常量字符*的模板方法专用化
- 两种专用方法中的相同代码
- C++隐式/显式模板方法专用化问题
- C++复杂类型的单一方法的模板专用化
- enable_if在类声明之外实现的方法专用化
- 模板化类和模板化方法的模板专用化语法
- 获取非专用标准::矢量容器的标准方法<bool>
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- boost:enable_if 在模板化类中定义专用方法
- 模板类的专用方法
- 从专用方法捕获异常