Re: эмм... variadic-pack в нешаблонную функцию
От: PM  
Дата: 13.10.16 05:17
Оценка: +1
Здравствуйте, niXman, Вы писали:

[...]


X>для фундаментальных типов все просто — преобразуем args в массив указателей на void, и добавляем какие-то ID`ы, идентифицирующие типы.

X>но со всеми остальными(в том числе и юзерскими типами) типами все как-то не перспективно...

tuple здесь не поможет, т.к. для разных Args будут разные типы tuple. RTTI в виде std::type_index тоже как-то не очень. Идея с массивом void* правильная, но вместо идентифкаторв типов можно передавать массив функций-обработчиков для значения каждого типа:

#include <iostream>

struct shared_buffer {};

// то что тебе нужно делать для каждого типа
shared_buffer do_pack(int arg);
shared_buffer do_pack(double arg);

struct foo {
    // пользовательскиме типы тоже не проблема
    friend shared_buffer do_pack(foo const& arg);
};


struct somestruct {
    template<typename... Args>
    shared_buffer pack(const Args&... args) {
        // заворачиваем do_pack для каждого типа в массив функций
        arg_pack_fn fns[] = { &wrap_do_pack<Args>... };
        // преобразуем аргументы в массив void const*
        void const* data[] = { std::addressof(args)... };

        return pack2(fns, data, sizeof...(Args));
    }

private:
    using arg_pack_fn = shared_buffer (*)(void const* arg);

    // обертка для функций do_pack(T) чтобы привести к arg_pack_fn
    template<typename T>
    static shared_buffer wrap_do_pack(void const* arg) {
        return do_pack(*static_cast<T const*>(arg));
    }
    
    shared_buffer pack2(arg_pack_fn pack_fns[], void const* args[], size_t count);
};

// implementation in .cpp

shared_buffer do_pack(int arg) {
    std::cout << arg << ' ';
}

shared_buffer do_pack(double arg) {
    std::cout << arg << ' ';
}

shared_buffer do_pack(foo const& arg) {
    std::cout << "foo ";
}

shared_buffer somestruct::pack2(arg_pack_fn pack_fns[], void const* args[], size_t count) {
    for (size_t i = 0; i != count; ++i) {
        pack_fns[i](args[i]);
    }
}

int main() {
  somestruct ss;
  ss.pack(foo{}, 1, 3.14); // should print "foo 1 3.14 "
}


http://ideone.com/Ol1KUx
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.