容器类有条件地定义方法



是否有可能(并且是一个好主意)根据其元素的类型有条件地定义一些容器类(template<typename ThingType> class Container)的方法?我第一次认为这是可能的阅读后std::enable_if,但现在我不确定我理解。

下面是我的尝试(点击这里在ideone上运行)。在std::is_base_of<ThingBase, ThingType>::valuefalse的情况下,将不定义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 << "hin";
}   
};

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()
我不打算让这个方法被重载。我希望终端用户可以随时使用它。这些p方法中只有一个,它应该只需要一个(相对简单的)签名。

我不打算重载这个方法。我希望终端用户可以随时使用它。这p个方法中只能有一个,并且应该只需要一个(相对简单的)签名。

这大大简化了练习。解决办法是……不做什么特别的事。

void p() {
m_things[0].printHi();
}

当隐式实例化类模板时,只有成员函数的声明与它一起实例化。在尝试使用成员之前,定义不会实例化。

所以你不需要做任何特别的事情。

如果在不能使用的情况下使用,则会出现错误。如果您仍然希望确保可衍生性,并在这种情况下产生描述性错误,则可以在成员函数体中添加static_assert。只需对条件使用is_base_of测试,并添加一个漂亮的字符串。

这是编写泛型实用程序时的常用方法。另一方面,SFINAE的主要目的是控制过载分辨率。但你不能在这里做。

相关内容

  • 没有找到相关文章

最新更新