0

我會簡單地張貼代碼:如何實現用戶友好的存取

#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>得到field_id_field_t類型的n個場?)

+0

在C++ 14的get函數中應該有這樣一個特性(也許有一些不同的功能,但確實有這樣的東西),但我也可能依賴於你使用的編譯器(如果它們已經實現了這個) – Creris 2014-10-17 15:24:51

+2

所以是的根據http://en.cppreference.com/w/cpp/utility/tuple/get你應該能夠獲得特定類型的元素 – Creris 2014-10-17 15:41:55

+0

@TheOne:謝謝,任何方式來完成這個在C + +11? – nakiya 2014-10-17 16:32:43

回答

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不止一次包含此類型,則這不會失敗 - 它會選擇該類型的第一個對象。

+0

不錯。我會通過代碼來理解。但它似乎正常工作。謝謝。 – nakiya 2014-10-17 18:11:39