2016-12-04 6 views
1

documentation для hana::keys говорит, что я могу использовать его в синтаксисе вызова функции, например. hana::keys(s) где s - это экземпляр класса, отвечающего концепции hana::Struct, и он возвращает последовательность ключевых объектов.Могу ли я использовать `hana :: keys` без экземпляра структуры?

Связанная функция, hana::accessors, возвращает последовательность функций доступа, которые могут быть использованы для захвата соответствующих элементов из экземпляра структуры.

hana::accessorscan be used in two ways:

hana::accessors(s) 
hana::accessors<S>() 

являются как юридические, constexpr функции, возвращающие то же самое, когда S = decltype(s) - последовательность, соответствующая структуре S.

Когда я пробую этот синтаксис с hana::keys, я получаю сообщение об ошибке. Вот MCVE, адаптировано из примера в hana документации:


#include <boost/hana.hpp> 
#include <boost/hana/define_struct.hpp> 
#include <boost/hana/keys.hpp> 
#include <iostream> 
#include <string> 

namespace hana = boost::hana; 

struct Person { 
    BOOST_HANA_DEFINE_STRUCT(Person, 
     (std::string, name), 
     (unsigned short, age) 
    ); 
}; 


// Debug print a single structure 

template <typename T> 
void debug_print_field(const char * name, const T & value) { 
    std::cout << "\t" << name << ": " << value << std::endl; 
} 


template <typename S> 
void debug_print(const S & s) { 
    std::cout << "{\n"; 

    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
    debug_print_field(hana::to<char const *>(key), hana::at_key(s, key)); 
    }); 

    std::cout << "}" << std::endl; 
} 

// Debug print compare two structures 

int main() { 
    Person john{"John", 30}, kevin{"Kevin", 20}; 

    debug_print(john); 
    std::cout << std::endl; 
    debug_print(kevin); 
    std::cout << std::endl; 
} 

$ g++-6 -std=c++14 -I/home/chris/boost/boost_1_61_0/ main.cpp 
main.cpp: In function ‘void debug_print(const S&)’: 
main.cpp:28:30: error: expected primary-expression before ‘>’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
          ^
main.cpp:28:32: error: expected primary-expression before ‘)’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
           ^

Он отлично работает, когда я использую hana::keys(s).

Но в моем фактическом приложении у меня нет экземпляра структуры, это только параметр шаблона.

Как взломать, я сделал это:

// Work around for `hana::keys` 

template <typename S> 
constexpr decltype(auto) get_hana_keys() { 
    return decltype(hana::keys(std::declval<S>())){}; 
} 

Я считаю, , что это работает на основе моего ограниченного понимания деталей реализации hana, описанных в доку. - hana::keys должен возвращать последовательность строк времени компиляции, и вся информация содержится в типе, поэтому просто получение типа и построение по умолчанию должно быть эквивалентным.

Когда я использую get_hana_keys<S>() в своем MCVE, тогда он компилируется и работает отлично.

Однако я не знаю, действительно ли это правильно, или если предположения, которые я делаю, выходят за рамки того, что позволяют мне позволить документы.

Я использую форсированную версию 1.61 и gcc 6.2.0.

То, что я хотел бы знать,

  • Есть хорошая причина, по которой hana::keys<S>() не работает, или это просто упущение? hana, похоже, был очень тщательно разработан, поэтому я склонен к тому, чтобы угадать себя здесь.

  • Есть ли что-то не так с созданным мной взломом или способом его улучшить?

ответ

2

Хороший вопрос!

Есть ли веская причина, что hana::keys<S>() не работает или это просто недосмотр?

Причина, по которой hana::keys<S>() не работает, заключается в том, что ее невозможно реализовать в общем случае. Действительно, keys изначально был рассчитан на hana::map, где ключи могли быть работоспособными и поэтому вам действительно нужен объект, чтобы вернуть что-то значимое. Тот факт, что объект не нужен для извлечения ключей hana::Struct, является просто совпадением.

Есть ли что-то не так с взломом, который я создал, или как его улучшить?

Технически hana::string не документирован как по умолчанию, конструктивно, поэтому по умолчанию, построение hana::tuple тех, не гарантируется. Однако это недосмотр, который я исправил в 1eebdb, так что вы в порядке.

Это, как говорится, возможно, более идиоматическое решением будет следующее:

template <typename S> 
constexpr auto get_hana_keys() { 
    return hana::transform(hana::accessors<S>(), hana::first); 
} 

На самом деле, это то, как мы определяем hana::keys для hana::Struct с.

Наконец, обратите внимание, что все, что связано с hana::Struct, будет гораздо лучше обслуживаться отражением на уровне языка, поэтому, пожалуйста, извините причудливую поддержку отражения, которую предоставляет Hana. В этой области действительно сложно сделать что-либо хорошее без поддержки языков.

 Смежные вопросы

  • Нет связанных вопросов^_^