Общий интерфейс для различных объектов шаблонного класса - PullRequest
0 голосов
/ 10 ноября 2018

Новичок в C ++ и наткнулся на такой код (также не уверен, что это правильный путь)

template<ReqType, RespType>
class StreamManager {
...
...
}

using UpstreamManager = StreamManager<UpstreamReq, UpstreamResp>;
using DownstreamManager = StreamManager<DownstreamReq, DownstreamResp>;
using SidestreamManager = StreamManager<SidestreamReq, SidestreamResp>;

Я хочу реализовать функцию, которая возвращает один из этих типов в зависимости от типа, переданного в функцию. Есть ли способ определить, что это какой-то общий тип.

**[ReturnType]** CreateStreamManager(StreamType type) {
    switch(type) {
        case upstream:
            return new UpstreamManager();
        case downstream:
            return new DownstreamManager();
        case sidestream:
            return new SidestreamManager();
    }
}

Есть ли способ определить ReturnType для этой функции CreateStreamManager?

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Начиная с C ++ 17 (я не уверен), вы можете использовать спецификатор auto в качестве возвращаемого типа. Я бы определил функцию следующим образом:

template<typename ReqType, typename RespType>
auto CreateStreamManager() {
    return new StreamManager<ReqType, RespType>();
}

Если тип можно определить во время компиляции, вы также можете использовать спецификатор constexpr:

constexpr auto CreateStreamManager(StreamType type) {
    switch (type) {
        case upstream:
        return new UpStreamManager();
    ...
}

Кстати, плохо выделять память и возвращать ее без умных указателей.

0 голосов
/ 10 ноября 2018

Вы можете «перегрузить» функцию следующим образом:

UpstreamManager* CreateStreamManager(UpstreamReq req) {
    return new UpstreamManager();
}
DownstreamManager* CreateStreamManager(DownstreamReq req) {
    return new DownstreamManager();
}

Или вы можете написать «фабричную функцию», но только если StreamManager наследует не шаблонный базовый класс, который может быть общим возвращаемым типом:

class BaseStreamManager {
    virtual ~BaseStreamManager() = default;
};

template<ReqType, RespType>
class StreamManager : public BaseStreamManager {
}

BaseStreamManager* CreateStreamManager(StreamType type) {
    switch(type) {
        case upstream:
            return new UpstreamManager();
        case downstream:
            return new DownstreamManager();
        case sidestream:
            return new SidestreamManager();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...