Помогите с вариадиками
От: SaZ  
Дата: 09.01.18 13:25
Оценка:
Доброго дня,

Подскажите, как корректно реализовать следующее:
Есть некоторый список несвязанных между собой (без общего предка) типов T1, T2, T3..., у каждого из которых есть статический метод StaticMeta.
Нужно написать функцию bool Validate<T1, T2, T3>(const MetaInfo& staticMeta) которая сравнит staticMeta с каждым из типов (staticMeta==T1::StaticMeta()).

Что-то не получается сделать нужные перегрузки. Пример кода (немного сложноват, но отражает задачу)
#include <iostream>
#include <string>
#include <memory>
#include <utility>
#include <cassert>
 
#define GENERATE_META(type)                 \
    public:                                 \
    static const MetaInfo& StaticMeta()     \
    {                                       \
        static MetaInfo meta{#type}; \
        return meta;                        \
    }
 
struct MetaInfo
{
    const std::string _id;
 
    explicit MetaInfo( std::string ti )
        : _id{std::move( ti )}{}
 
    bool operator==(const MetaInfo& rhs) const
    {
        return _id == rhs._id;
    }
 
    bool operator!=(const MetaInfo& rhs) const
    {
        return operator==(rhs);
    }
};
 
// Inheritance is just for example
// In real project code is generated by tools
struct Base
{
protected:
    Base() = default;
};
 
struct MyType1 : Base
{
    GENERATE_META(MyType1)
    int _dummy = 1;
};
 
struct MyType2 : Base
{
    GENERATE_META(MyType2)
    float _dummy = 2.f;
};
 
struct MyType3 : Base
{
    GENERATE_META(MyType3)
    std::string _dummy = "gg";
};
 
 
class Table
{
public:
    template< typename T >
    static Table Create()
    {
        auto data = std::make_shared<T>();
        auto meta = &T::StaticMeta();
        return { data, meta };
    }
 
    const std::shared_ptr<Base>& Data() const{ return _data; }
    const MetaInfo& Meta() const{ return *_meta; }
 
private:
    Table( std::shared_ptr<Base> data, const MetaInfo * meta )
        : _data{std::move(data)}
        , _meta{meta}
    {}
 
private:
    std::shared_ptr<Base> _data;
    const MetaInfo * const _meta = nullptr;
};
 
template< typename T >
void Print( const Table& table )
{
    assert( table.Meta() == T::StaticMeta() );
    const auto& data = *static_cast<T*>(table.Data().get());
    std::cout << table.Meta()._id << " -> " << data._dummy << "\n";
}
 
/////////////////////////////////////////////////////////////////////
 
template< typename T >
bool Validate( const Table& table )
{
    if ( table.Meta() == T::StaticMeta() )
    {
        Print<T>( table );
        return true;
    }
 
    return false;
}
 
template< typename T, typename ...Tables >
bool Validate( const Table& table )
{
    if ( Validate<T>( table ) )
        return true;
 
    return Validate<Tables...>(table);
}
 
 
int main()
{
    const auto t1 = Table::Create<MyType1>();
    const auto t2 = Table::Create<MyType2>();
    const auto t3 = Table::Create<MyType3>();
 
    const auto r1 = Validate<MyType1, MyType2>(t1);
    assert( r1 );
    const auto r2 = Validate<MyType1, MyType2>(t2);
    assert( r2 );
    const auto r3 = Validate<MyType1, MyType2>(t3);
    assert( !r3 );
 
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.