2015-09-20 15 views
7

Boost Hana cung cấp khả năng nội quan trên các lĩnh vực thành viên lớp một cách đơn giản và đẹp:Có thể quan tâm đến các phương pháp sử dụng Boost Hana không?

// define: 

struct Person { 
    std::string name; 
    int age; 
}; 

// below could be done inline, but I prefer not polluting the 
// declaration of the struct 
BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age); 

// then: 

Person john{"John", 30}; 
hana::for_each(john, [](auto pair) { 
    std::cout << hana::to<char const*>(hana::first(pair)) << ": " 
      << hana::second(pair) << std::endl; 
}); 

Tuy nhiên, các tài liệu chỉ đề cập đến thành viên lĩnh vực. Tôi cũng muốn nhìn vào các phương pháp. Tôi đã cố gắng mở rộng ví dụ một cách ngây thơ bằng một phương thức:

struct Foo { 
    std::string get_name() const { return "louis"; } 
}; 

BOOST_HANA_ADAPT_STRUCT(::Foo, get_name); 

Biên dịch này. Tuy nhiên, ngay sau khi tôi cố gắng sử dụng nó, sử dụng mã tương tự như ở trên (for_each ...), tôi nhận được nhiều lỗi biên dịch. Vì không có ví dụ nào thể hiện sự mâu thuẫn của các phương thức, tôi tự hỏi liệu nó có được hỗ trợ hay không.

+0

Nó được hỗ trợ, nhưng tôi đồng ý rằng nó có thể được tài liệu tốt hơn. Bạn có thể xem phần _Minimal complete definition_ của khái niệm ['Struct'] (http://ldionne.com/hana/structboost_1_1hana_1_1Struct.html). Tôi không có thời gian để viết một câu trả lời đầy đủ ngay bây giờ, nhưng tôi sẽ cố gắng làm điều đó trong những ngày tiếp theo (và cũng cập nhật hướng dẫn). –

Trả lời

9

Câu trả lời ban đầu của tôi là crap; xin lỗi vì chuyện đó. Đây là một viết lại thực sự trả lời câu hỏi.

Tôi vừa thêm macro để cho phép dễ dàng xác định Struct với trình tiếp cận tùy chỉnh. Dưới đây là cách bạn có thể thực hiện:

#include <boost/hana/adapt_adt.hpp> 
#include <boost/hana/at_key.hpp> 
#include <boost/hana/string.hpp> 
#include <cassert> 
#include <string> 
namespace hana = boost::hana; 

struct Person { 
    Person(std::string const& name, int age) : name_(name), age_(age) { } 
    std::string const& get_name() const { return name_; } 
    int get_age() const { return age_; } 
private: 
    std::string name_; 
    int age_; 
}; 

BOOST_HANA_ADAPT_ADT(Person, 
    (name, [](auto const& p) { return p.get_name(); }), 
    (age, [](auto const& p) { return p.get_age(); }) 
); 

int main() { 
    Person bob{"Bob", 30}; 
    assert(hana::at_key(bob, BOOST_HANA_STRING("name")) == "Bob"); 
    assert(hana::at_key(bob, BOOST_HANA_STRING("age")) == 30); 
} 

Mã đó phải hoạt động trên master. Ngược lại, nếu bạn cần kiểm soát nhiều hơn định nghĩa của accessors của bạn hoặc các phím sử dụng để lập bản đồ cho họ, bạn cũng có thể xác định toàn bộ sự việc bằng tay:

namespace boost { namespace hana { 
    template <> 
    struct accessors_impl<Person> { 
     static auto apply() { 
      return hana::make_tuple(
       hana::make_pair(BOOST_HANA_STRING("name"), [](auto&& p) -> std::string const& { 
        return p.get_name(); 
       }), 
       hana::make_pair(BOOST_HANA_STRING("age"), [](auto&& p) { 
        return p.get_age(); 
       }) 
      ); 
     } 
    }; 
}} 

Bạn có thể tìm thêm thông tin về làm thế nào để xác định Struct s trong reference cho khái niệm Struct.

+1

@seertaak Điều đó có trả lời câu hỏi của bạn không? Nếu vậy, bạn có thể vui lòng chấp nhận nó và nếu không, hãy cho tôi biết những gì còn thiếu để tôi có thể giúp bạn và có lẽ cải thiện khả năng sử dụng của thư viện. –

+0

Vâng, đúng vậy! Xin lỗi vì trả lời muộn. – seertaak

Các vấn đề liên quan