是否有可能(并且是个好主意template<typename ThingType> class Container
)根据其容器的类型有条件地为某些容器类()定义方法?在阅读了有关内容后std::enable_if
,我首先认为这是有可能的,但是现在我不确定我是否理解。
以下是我的尝试(单击此处可在ideone上运行)。在这种情况下std::is_base_of<ThingBase, ThingType>::value
是false
,对于返回类型p
将不会被定义。我认为编译器将只实例化没有该方法的类的对象。但是事实证明它不能编译。
有另一种工具可以完成这项工作吗?还是应该编写两个Container
类似的类,它们根据行为具有不同的行为ThingType
?也许这是专业化的工作。
#include <iostream>
#include <type_traits>
#include <vector>
class ThingBase {
public:
virtual void printHi() = 0;
};
class Thing : public ThingBase
{
void printHi(){
std::cout << "hi\n";
}
};
template<typename ThingType>
class Container{
private:
std::vector<ThingType> m_things;
public:
typename std::enable_if<std::is_base_of<ThingBase, ThingType>::value>::type p()
{
m_things[0].printHi();
};
};
int main() {
//Container<Thing> stuff; // works!
Container<int> stuff; // doesn't work :(
return 0;
}
来自编译器的错误消息是
prog.cpp: In instantiation of ‘class Container<int>’:
prog.cpp:36:17: required from here
prog.cpp:26:78: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
typename std::enable_if<std::is_base_of<ThingBase, ThingType>::value>::type p()
@StoryTeller-Unslander Monica我不希望这种方法被重载。我希望最终用户可以使用它。这些p
方法只有一种,并且应该只采用一种(相对简单的)签名。
我不打算将此方法重载。我希望最终用户可以使用它。这p种方法中只有一种,并且应该只采用一种(相对简单的)签名。
这大大简化了练习。解决方案是...什么都不做。
void p() {
m_things[0].printHi();
}
当隐式实例化一个类模板时,只有成员函数的声明与其一起被实例化。在尝试使用该成员之前,不会实例化定义。
因此,您无需执行任何特殊操作。如果无法使用该错误,则会发生错误。
如果仍然希望确保可导性并在这种情况下产生描述性错误,则可以将a添加static_assert
到成员函数主体中。只需将is_base_of
测试用于条件,然后添加一个漂亮的字符串即可。
这是编写通用实用程序时的常用方法。另一方面,SFINAE的主要目的是控制过载分辨率。但是您不是在这里做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句