我只是发布代码:
#include <tuple>
namespace primary_protocol
{
namespace
{
typedef uint64_t field_id_t;
typedef uint64_t field_size_t;
typedef uint64_t msg_id_t;
typedef uint64_t msg_size_t;
}
struct field_header
{
field_id_t _id;
field_size_t _size;
};
static const size_t field_header_sz = sizeof(field_header);
template<class TFieldType, field_id_t id>
struct field
{
private:
public:
field_id_t _id = id;
field_size_t _size = sizeof(*this);
TFieldType _value;
};
struct message_header
{
msg_id_t _id;
msg_size_t _size;
};
static const size_t msg_header_sz = sizeof(message_header);
template<msg_id_t msg_id, class... TFields>
struct message
{
msg_id_t _id;
msg_size_t _size = sizeof(*this);
std::tuple<TFields...> fields;
};
}
namespace impl
{
typedef uint64_t field_id_t;
typedef uint64_t msg_id_t;
static const size_t field_name_sz = 256;
static const size_t msg_name_sz = 256;
typedef primary_protocol::field<field_id_t, 0> field_id_field_t;
typedef primary_protocol::field<char[field_name_sz], 1> field_name_field_t;
typedef primary_protocol::field<msg_id_t, 2> msg_id_field_t;
typedef primary_protocol::field<char[msg_name_sz], 3> msg_name_field_t;
typedef primary_protocol::message<0, field_id_field_t, field_name_field_t> field_definition_msg_t;
typedef primary_protocol::message<1, msg_id_field_t, msg_name_field_t> msg_declaration_msg_t;
}
#include <iostream>
#include <string.h>
using namespace std;
int main(int argc, char **argv)
{
impl::field_definition_msg_t field_def_msg;
std::get<0>(field_def_msg.fields)._value = 10;
strcpy(std::get<1>(field_def_msg.fields)._value, "hello");
cout << std::get<0>(field_def_msg.fields)._value << endl
<< std::get<1>(field_def_msg.fields)._value << endl;
}
我的问题是std::get<0>(field_def_msg.fields)._value = 10
形式的主要功能中的访问者。假设field_ref<field_id_field_t>(field_def_msg) = 10
中的每个类型都是唯一的,有没有办法实现像tuple
这样的东西? (此外,如果它们不是唯一的,可以使用field_ref<field_id_field_t, n>
来获取n
类型的field_id_field_t
字段吗?)
答案 0 :(得分:3)
如评论中所述,您正在寻找std::get
的C ++ 14重载。简化的等效实现(对于C ++ 11)如下所示:
template <typename T, std::size_t counter = 0, typename... A> struct find_;
template <typename T, typename F, typename... Tail, std::size_t counter>
struct find_<T, counter, F, Tail...> : find_<T, counter+1, Tail...> {};
template <typename T, typename... Tail, std::size_t counter>
struct find_<T, counter, T, Tail...> : std::integral_constant<std::size_t, counter> {};
template <typename T, typename... Args>
using find = find_<T, 0, Args...>;
template< class T, class... Types >
constexpr T&& get(std::tuple<Types...>&& t)
{
return std::get<find<T, Types...>::value>(std::move(t));
}
template< class T, class... Types >
constexpr T const& get(std::tuple<Types...> const& t)
{
return std::get<find<T, Types...>::value>(t);
}
template< class T, class... Types >
constexpr T& get(std::tuple<Types...>& t)
{
return std::get<find<T, Types...>::value>(t);
}
Demo。请注意,如果tuple
不止一次包含此类型,则无法编译 - 它会选择该类型的第一个对象。