2017-01-22 4 views
0

Мне нужно преобразовать кортеж в массив байтов. Это код, я использую, чтобы преобразовать массив байтов:Определить указатели в кортеже C++ 11

template< typename T > std::array< byte, sizeof(T) > get_bytes(const T& multiKeys) 
    { 
    std::array< byte, sizeof(T) > byteArr ; 
    const byte* start = reinterpret_cast< const byte* >(std::addressof(multiKeys)) ; 
    const byte* end = start + sizeof(T); 
    std::copy(start, end, std::begin(byteArr)); 
    return byteArr; 
    }  

Вот как я это называю:

void foo(T... keyTypes){ 
     keys = std::tuple<T... >(keyTypes...); 
     const auto bytes = get_bytes(keys); 
    } 

мне нужно увеличить этот код такой, что, когда указатель является частью кортежа , Я разыгрываю его по значению, а затем передаю новый кортеж без указателей на функцию get_bytes(). Как определить наличие указателя в кортеже? Затем я могу перебирать кортеж и разыменования его с:

std::cout << *std::get<2>(keys) << std::endl; 

ответ

0

Добавить тривиальную перегрузку: T get_bytes(T const* t) { return getBytes(*t); }.

+0

Я думаю, что это работает, только если все элементы кортежа являются указателями. Что, если один элемент кортежа является char *, а остальные - int. – jok

+0

@jok: Затем вы вызываете 'char get_bytes (char const *)' для указателя и 'int get_bytes (int)' для целых чисел. Просто уточнить: это, конечно, предполагает, что вы перебираете все элементы кортежа и вызываете 'get_bytes' для каждого отдельного элемента. – MSalters

0

Это было бы легко с C++ 14:

#include <iostream> 
#include <tuple> 
#include <utility> 

template <class T> decltype(auto) get_dereferenced_value(T &&value) { 
    return std::forward<T>(value); 
} 

template <class T> decltype(auto) get_dereferenced_value(T *value) { 
    return *value; 
} 

template <class Tuple, class Indexes> struct get_dereferenced_tuple_impl; 

template <class... Args, size_t... Index> 
struct get_dereferenced_tuple_impl<std::tuple<Args...>, 
            std::integer_sequence<size_t, Index...>> { 
    decltype(auto) operator()(std::tuple<Args...> const &originalTuple) { 
    return std::make_tuple(
     get_dereferenced_value(std::get<Index>(originalTuple))...); 
    } 
}; 

template <class Tuple> 
decltype(auto) get_dereferenced_tuple(Tuple const &tupleValue) { 
    return get_dereferenced_tuple_impl< 
     Tuple, 
     std::make_integer_sequence<size_t, std::tuple_size<Tuple>::value>>{}(
     tupleValue); 
} 

int main() { 
    char c = 'i'; 
    std::tuple<char, char *> t{'h', &c}; 
    auto t2 = get_dereferenced_tuple(t); 
    std::cout << std::get<0>(t2) << std::get<1>(t2) << "\n"; 
    return 0; 
} 

Если вы не можете использовать C++ 14, то вы должны написать более подробные decltype выражения, а также включают в себя an implementation из std::(make_)integer_sequence.

У этого есть недостаток: копии будут сделаны перед копированием байтов. Кортеж ссылок не является хорошей идеей. Наиболее эффективной версией будет get_bytes, способный сериализовать весь смешанный кортеж напрямую.