Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Определение типов в parameter pack 
:(
    Опции темы
Tiarwe
Дата 6.9.2014, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 24.8.2011

Репутация: нет
Всего: нет



Здравствуйте! Подскажите, как можно пройтись по типам передаваемых в parameter pack.

Код

template<typename... A>
void func(A... a)
{
    const int size = sizeof...(a);

    // тут нужно циклом пройтись в теле которого будет сравнение типов
    // if(typeid(a[1, 2... n]) == typeid(T)) {...}
}

int main()
{
    int a = 1;
    float b = 2.0f;
    bool c = false;

    func(a, b, c);

    return 0;
}

PM MAIL   Вверх
Tiarwe
Дата 6.9.2014, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 24.8.2011

Репутация: нет
Всего: нет



Запилил, может кому пригодится:

Код

#include <tuple>
#include <string>

template<typename T>
std::string GetType(T t)
{
    if(typeid(t) == typeid(int))
    {
        return "I";
    }

    if(typeid(t) == typeid(float))
    {
        return "F";
    }

    if(typeid(t) == typeid(bool))
    {
        return "B";
    }

    return "?";
}

template<typename Tuple, std::size_t I>
struct TupleTypes
{
    static std::string Get(const Tuple& tuple)
    {
        std::string lResult;
        lResult += TupleTypes<Tuple, I - 1>::Get(tuple);

        auto lValue = std::get<I>(tuple);
        lResult += GetType(lValue);

        return lResult;
    }
};

template<typename Tuple>
struct TupleTypes<Tuple, 0>
{
    static std::string Get(const Tuple& tuple)
    {
        auto lValue = std::get<0>(tuple);
        std::string& lResult = GetType(lValue);

        return lResult;
    }
};

template<typename Tuple>
std::string GetTupleTypes(const Tuple& tuple)
{
    static const size_t lSize = std::tuple_size<Tuple>::value;
    std::string lResult = TupleTypes<Tuple, lSize - 1>::Get(tuple);

    return lResult;
}

template<typename... A>
std::string GetTypes(A... a)
{
    auto lTuple = std::make_tuple(a...);

    std::string lResult = GetTupleTypes(lTuple);

    return lResult;
}

int main()
{
    std::string lTypes = GetTypes(1, 2.0f, false, "hello");

    return 0;
}

PM MAIL   Вверх
Lukkoye
Дата 6.9.2014, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: 1
Всего: 1



Исправил ошибки компиляции, 
Оптимизировал промежуточные вычисления
Удалил лишние копирующие конструкторы
http://rextester.com/HAA37835
Но все равно код ужассен и избыточен.

Код

#include  <iostream>
#include  <typeinfo>
#include  <tuple>
#include  <string>


using namespace std;

template<typename T> std::string GetType(const T& t)
{
    if(typeid(t) == typeid(int))
        return "I";
    if(typeid(t) == typeid(float))
        return "F";
    if(typeid(t) == typeid(bool))
        return "B";
    return "?";
}
template<typename Tuple, std::size_t I> struct TupleTypes
{
    static std::string Get(const Tuple& tuple)
    {
        std::string lResult;
        lResult += TupleTypes<Tuple, I - 1>::Get(tuple);
        auto lValue = std::get<I>(tuple);
        lResult += GetType(lValue);
        return lResult;
    }
};
template<typename Tuple>struct TupleTypes<Tuple, 0>
{
    static std::string Get(const Tuple& tuple)
    {
        const auto lValue = std::get<0>(tuple);
        return GetType(lValue);
    }
};
template<typename Tuple> std::string GetTupleTypes(const Tuple& tuple)
{
    static const size_t lSize = std::tuple_size<Tuple>::value;
    return TupleTypes<Tuple, lSize - 1>::Get(tuple);
}
template<typename... A> std::string GetTypes(A... a)
{
    const auto lTuple = std::make_tuple(a...);
    return GetTupleTypes(lTuple);
}
int main()
{
    std::string lTypes = GetTypes(1, 2.0f, false, "hello");
    cout<<"result = "<<lTypes<<endl;
    return 0;
}


Вот упрощенная версия:
(иллюстрирует технику работы с пакованными аргументами)
http://rextester.com/NELZ86428

Код

#include <typeinfo>
#include <string>
#include <iostream>
using namespace std;

template<class A> ::std::string func(const A& a)
{
    cout<<"type = "<< typeid(a).name()<<endl;
    return typeid(a).name();
}
template<class A, class... Args> ::std::string func(const A& a, const Args&...  args)
{
    cout<<"type = "<< typeid(a).name()<<endl;
    return typeid(a).name() + func(args... );
}

int main()
{
    std::cout << "Hello, world!\n";
    func(0,true);
}


Ответ на вопрос сабжа: работа с variardic template
С учетом дизайна из второго сообщения данной темы
http://rextester.com/DBVNJZ68131


Код

#include <map>
#include <string>
#include <typeinfo>
#include <iostream>
using namespace std;


struct proccessor
{
    typedef ::std::string            str;
    typedef ::std::map<str, str>     mymap;

    template<class A> static str proccess(const A& a)
    {
        cout<<"type = "<< name(typeid(a)) <<endl;
        return name(typeid(a));
    }
    
    template<class A, class... Args> static str proccess(const A& a, const Args&...  args)
    {
        cout<<"type = "<< name(typeid(a)) <<endl;
        return name(typeid(a)) + proccess(args... );
    }
private:
    static const str& unkown()
    {
        static str s="?";
        return s;
    }
    static const str& name(const str& type)
    {
        const auto it = get().find(type);
        if(it==get().end())
            return unkown();
        return it->second;
    }
    static const str& name(const ::std::type_info& i)
    {
        return name( i.name() );
    }
    static bool init(mymap& m)
    {
        m[typeid(int).name()   ] = "int"   ;
        m[typeid(bool).name()  ] = "bool"  ;
        m[typeid(float).name() ] = "float" ;
        return true;
    }
    static mymap& get()
    {
        static mymap m;
        static bool initializer( init(m) );
        return m;
    }
};





int main()
{
    std::cout << "Hello, world!\n";
    
    proccessor::proccess(0,true, "hello");
}



Это сообщение отредактировал(а) Lukkoye - 6.9.2014, 15:17
PM MAIL   Вверх
Tiarwe
Дата 7.9.2014, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 24.8.2011

Репутация: нет
Всего: нет



Lukkoye, огромное спасибо! Упрощенная версия сильно помогла, набросок пока выглядит так:

Код

#include <typeinfo>
#include <string>
#include <iostream>
using namespace std;

template<typename T>
std::string GetType(T t)
{
    if(typeid(t) == typeid(int))
    {
        return "I";
    }

    if(typeid(t) == typeid(float))
    {
        return "F";
    }

    if(typeid(t) == typeid(bool))
    {
        return "B";
    }

    return "?";
}

template<typename T>
std::string GetTypes(const T& t)
{
    static std::string lResult = GetType(t);

    return lResult;
}

template<typename T, typename... Args>
std::string GetTypes(const T& t, const Args&...  args)
{
    static std::string lResult = GetType(t) + GetTypes(args...);

    return lResult;
}

int main()
{
    std::string lResult1 = GetTypes(0, true, 1.0f, "hello");

    return 0;
}


На функцию std::string GetType(T t) пока не стоит обращать внимания, т.к. она будет переписана со специализациями под нужные типы. Ну а делалось всё это ради вызовов через JNI, для определения сигнатур типов параметров, передаваемых в метод.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0734 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.