簡體   English   中英

使用 enable_if 決定成員變量的類型

[英]Using enable_if to decide the type of a member variable

template <typename ...T>
class BaseEvent
{
    BaseEvent(const unsigned int index, const uint8_t id, const std::variant<T...> data) : m_index(index), m_id(id), m_data(m_data){};
    virtual ~BaseEvent();

    template <typename V>
    const V get()
    {
        static_assert(constexpr std::is_same_v<V, T...>);
        return std::get<V>(m_data);
    };

protected:
    unsigned int m_index;
    uint8_t m_id;
    std::variant<T...> m_data;
    
    // pseudocode:
    // enable_if(sizeof(T...) > 1)
    // then: std::variant<T...> m_data
    // else: T m_data
};

然而在后面的代碼中,

template <class T>
class StringEvent : public BaseEvent<T>
{
    virtual ~StringEvent();
    const T string() { return get<T>(); };
};

僅將單個類型傳遞給BaseEvent將無法創建variant ,因為在這種情況下無論如何它都是無用的。 T...僅是單一類型時,如何使用enable_if創建T類型的m_data

我已經做了你想做的事,所以我知道你需要什么。 要同時處理單個消息和多個消息類型,請使用std::variant<std::monostate, T...> 此外,您對is_same_v<>的使用不正確。 您只能使用一種類型,而不是多種類型。

所以你需要這樣的代碼:

template <typename ...T>
class BaseEvent
{
    BaseEvent(const unsigned int index, const uint8_t id, const std::variant<T...> data) : m_index(index), m_id(id), m_data(m_data){}; 
    // ^-- There is a small bug here in creating variant(different types). you need to solve, and use in-place for variant.
    virtual ~BaseEvent();

    template <typename V>
    const V get()
    {
        static_assert(is_valid_type<V>() || std::is_same_v<V, std::monostate>);
        return std::get<V>(m_data);
    };

protected:
    unsigned int m_index;
    uint8_t m_id;
    std::variant<std::monostate, T...> m_data;

private:
    template<typename U>
    constexpr static bool is_valid_type() {
        return (std::is_same_v<U, T> || ...);
    }    
};

我的主要代碼要復雜得多,我只是為此提取了一小部分,因此請謹慎使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM