有条件地定义容器类的方法

泰勒

是否有可能(并且是个好主意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 << "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方法只有一种,并且应该只采用一种(相对简单的)签名。

讲故事的人-Unslander Monica

我不打算将此方法重载。我希望最终用户可以使用它。这p种方法中只有一种,并且应该只采用一种(相对简单的)签名。

这大大简化了练习。解决方案是...什么都不做。

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

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

因此,您无需执行任何特殊操作。如果无法使用该错误,则会发生错误。

如果仍然希望确保可导性并在这种情况下产生描述性错误,则可以将a添加static_assert到成员函数主体中。只需将is_base_of测试用于条件,然后添加一个漂亮的字符串即可。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章