微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

容器类的有条件定义方法 编辑:

如何解决容器类的有条件定义方法 编辑:

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

下面是我的尝试(点击 here 在 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 方法中只有一个,并且应该只需要一个(相对简单的)签名。

解决方法

我不打算重载这个方法。我希望它在有意义的时候可供最终用户使用。这p个方法只会有一个,而且应该只需要一个(相对简单的)签名。

这大大简化了练习。解决方案是……不做任何特别的事情。

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

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

所以你不需要做任何特别的事情。不能使用时使用会报错。

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。