MPL-Placeholder-Frage
-
Tag,
ich versuche hier, die Größen von float-Arrays in einer MPL-Sequenz zusammenzuzählen, also zB:
typedef std::tr1::array < float, 2 > vector2_t; typedef std::tr1::array < float, 3 > vector3_t; typedef boost::mpl::vector < vector3_t, vector2_t > sequence_; enum { size = sizeof(float) * 3 + sizeof(float) * 2 };Das soll halt automatisch gehen. Ich bin bisher auf diese Lösung gekommen:
namespace detail { template < typename > struct calc_attrib_size; template < typename T, unsigned int N > struct calc_attrib_size < std::tr1::array < T, N > > { enum { value = sizeof(T) * N }; }; } typedef std::tr1::array < float, 2 > vector2_t; typedef std::tr1::array < float, 3 > vector3_t; typedef boost::mpl::vector < vector3_t, vector2_t > sequence_t; typedef typename boost::mpl::fold < sequence_t, boost::mpl::int_ < 0 >, boost::mpl::plus < boost::mpl::int_ < detail::calc_attrib_size < boost::mpl::placeholders::_2 // error > ::value >, boost::mpl::placeholders::_1 > > ::type vertex_size_t; enum { vertex_size = vertex_size_t::value };Das klappt wunderbar, wenn ich boost::mpl::placeholders::_2 durch zB std::tr1::array < float, 3 > ersetze, d.h. der Placeholder wird nicht richtig aufgelöst, da er incomplete ist an der Stelle. Lösungsvorschläge?
Btw. ein einfaches sizeof_ < boost::mpl::placeholders::_2 > hatte ich vorher, aber es stellt sich heraus, dass sizeof(std::tr1::array < float, 3 >) != sizeof(float) * 3. Stattdessen ists 16 Byte groß, ich nehm mal an aus Alignment-Gründen.
-
Ich kenne mich selber nicht so gut aus in der MPL, aber ich denke hiermit sollte dir geholfen sein:
http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/tutorial/handling-placeholders.htmlDein Problem ist ja, dass dein
struct calc_attrib_sizenicht mit Placeholders umgehen kann. Im Link und den weiterführenden Links steht, wie man dies erreichen kann. Wie das genau auf deinstructanzuwenden ist, will ich mir jetzt nicht überlegen
Hoffe aber du kommst damit weiter.
Grüssli
-
Ja, die Lösung war tatsächlich einfach.
calc_attrib_size damit ersetzen:
template < typename > struct calc_attrib_size; template < typename T, unsigned int N > struct calc_attrib_size < std::tr1::array < T, N > > : public boost::mpl::integral_c < unsigned int, sizeof(T) * N > { };Und den MPL-Code damit ersetzen:
typedef typename boost::mpl::fold < sequence_t, boost::mpl::int_ < 0 >, boost::mpl::plus < detail::calc_attrib_size < boost::mpl::placeholders::_2 >, boost::mpl::placeholders::_1 > > ::type vertex_size_t;Hierbei besonders auf mpl::plus achten - ist einfacher als der vorherige Code
