To jest moje pierwsze pytanie do tej wielkiej wymiany wiedzy i mam nadzieję, że znajdę jakąś pomoc.Jak iterować nad boost :: fusion asocjacyjną strukturą i dostępem w ogólny sposób klucze
Próbuję wprowadzić ogólny sposób tworzenia funkcji PrintTo (później do wykorzystania w GoogleTest).
Poniższy kod wykonuje tylko połowę zlecenia. To tylko drukuje wartości zdefiniowanej struktury Foo::Bar
#include <iostream>
#include <sstream>
#include <string>
#include <boost/fusion/container.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/adapted/struct/define_assoc_struct.hpp>
#include <boost/fusion/include/define_assoc_struct.hpp>
namespace Foo
{
namespace Keys
{
struct StringField;
struct IntField;
};
}
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
(Foo), Bar,
(std::string, stringField, Foo::Keys::StringField)
(int, intField, Foo::Keys::IntField))
struct fusion_printer_impl
{
std::ostream& _os;
fusion_printer_impl(std::ostream& os)
: _os(os) {}
template <typename T>
void operator() (T& v) const
{
_os << v << std::endl;
}
};
void PrintTo(Foo::Bar const& v, std::ostream* os)
{
boost::fusion::for_each(v, fusion_printer_impl(*os));
}
int main()
{
Foo::Bar fb("Don't panic!", 42);
std::ostringstream temp;
PrintTo(fb, &temp);
std::cout << temp.str() << std::endl;
}
Więc co szukam jest sposobem drukowania automatycznie Foo::Keys
również. Zajrzałem do wygenerowanego przez makro kodu BOOST_FUSION_DEFINE_ASSOC_STRUCT i o ile widzę Klawisze są dostępne jako static const char * boost :: fusion :: extension :: struct_member_name :: call().
Zajrzałem do kodu fusion :: for_each i do tej pory widzę tylko sposób na "skopiowanie" całego kodu, tak aby wywołanie fusion_printer_impl :: operator() zostało wywołane z dwoma parametrami: kluczem i wartościami. Zanim przejdę do tego kierunku, chciałbym wiedzieć, czy istnieją łatwiejsze sposoby, aby to osiągnąć.
Wiem, że możliwe jest zdefiniowanie explicite boost :: fusion :: map. Tutaj uzyskuje się automatycznie dostęp poprzez fuzję :: pair do typu klucza i wartości. Ale obecnie nie ma dla mnie opcji.
Tak więc każda pomoc tutaj jest mile widziany.
Dzięki za odpowiedź. Pomogło mi to znacznie dalej. Zmieniając parametr result_type funktora na std :: string i przesyłając wynik frazy boost :: fusion :: iter_fold bezpośrednio do * os, mogę uniknąć _ugly_ const_cast. –
Nawet o tym nie wspominając, zostawiając kogoś tam, aby jego dusza została zmiażdżona przez niezgłębione abstrakcje, a ponure mnóstwo błędów kompilatora byłoby bardzo nieludzkie ... – dsign
Wiem, o czym mówisz. Przynajmniej VC10 i Clang znacznie się poprawiły. (Nie wiem o gcc). Mając błąd w korzystaniu z boost :: spirit sprawia zawsze radość :-( –