扩展两个类的参数的语法

Geo*_*ard 3 c++ inheritance

在Java中,可以声明参数实现多个接口.您必须使用泛型语法,但您可以:

public <T extends Appendable & Closeable> void spew(T t) {
    t.append("Bleah!\n");
    if (timeToClose())
        t.close();
}
Run Code Online (Sandbox Code Playgroud)

在C++中,常见的模式是使用仅包含纯虚函数的类作为接口:

class IAppendable {
public:
    virtual void append(const std::string&) = 0;
};

class ICloseable {
public:
    virtual void close() = 0;
};
Run Code Online (Sandbox Code Playgroud)

编写一个需要ICloseable(这只是多态)的函数是微不足道的:

void closeThis(ICloseable&);
Run Code Online (Sandbox Code Playgroud)

但是,什么是在Java例如需要一个参数来作为函数的签名,从继承 ICloseable IAppendable

Que*_*tin 5

以下是使用标准工具编写的方法:

template <class T>
std::enable_if_t<
    std::is_base_of<IAppendable, T>{} && std::is_base_of<ICloseable, T>{},
    void
> closeThis(T &t) {
    t.append("end");
    t.close();
}
Run Code Online (Sandbox Code Playgroud)

住在Coliru

如果有更多的基类,我建议制作一个更简洁的类型特征来检查它们enable_if:

constexpr bool allTrue() {
    return true;
}

template <class... Bools>
constexpr bool allTrue(bool b1, Bools... bools) {
    return b1 && allTrue(bools...);
}

template <class T, class... Bases>
struct all_bases {
    static constexpr bool value = allTrue(std::is_base_of<Bases, T>{}...);

    constexpr operator bool () const {
        return value;
    }
};

template <class T>
std::enable_if_t<
    all_bases<T, IAppendable, ICloseable>{},
    void
> closeThis(T &t) {
    t.append("end");
    t.close();
}
Run Code Online (Sandbox Code Playgroud)