如何将 std::tuple 类型与 boost::mpl 算法一起使用?
boost::mpl
算法似乎无法在开箱即用的 std::tuple
类型上工作,例如,以下内容无法编译(boost-1.46. 0,g++ 快照 2011-02-19):
#include <tuple>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
namespace mpl=boost::mpl;
typedef mpl::vector<int,float,bool> types;
static_assert(mpl::contains<types, float>::value, "vector contains bool");
typedef std::tuple<int,float,bool> types2;
// the following does not compile:
// error: no class template named ‘apply’ in ‘struct boost::mpl::contains_impl<boost::mpl::non_sequence_tag>’
static_assert(mpl::contains<types2, float>::value, "tuple contains bool");
使 boost::mpl
算法在 std::tuple
上工作的最简单方法是什么?
- 做evtl。
boost::fusion
提供此功能(就像boost::tuple
一样)吗? - 如果没有,是否可以轻松地将 boost::tuple 的融合实现转移到 std::tuple ?
- 如果不是,我真的必须实现 MPL 文档中列出的所有内在元函数 或者哪些就足够了? (文档只说“许多内在元函数提供了在大多数情况下都有效的默认实现”,但尚不清楚到底是哪些元函数。并且一些仅提供 begin 和 end 的测试并没有带我去任何地方)。
The boost::mpl
algorithms seem not to be able to work on std::tuple
types out of the box, e.g., the following does not compile (boost-1.46.0, g++ snapshot 2011-02-19):
#include <tuple>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
namespace mpl=boost::mpl;
typedef mpl::vector<int,float,bool> types;
static_assert(mpl::contains<types, float>::value, "vector contains bool");
typedef std::tuple<int,float,bool> types2;
// the following does not compile:
// error: no class template named ‘apply’ in ‘struct boost::mpl::contains_impl<boost::mpl::non_sequence_tag>’
static_assert(mpl::contains<types2, float>::value, "tuple contains bool");
What is the easiest way to make the boost::mpl
algorithms work on std::tuple
?
- Does evtl.
boost::fusion
provide this functionality (as it does so forboost::tuple
)? - If not, would it be possible to carry over the fusion implementation for
boost::tuple
tostd::tuple
easily? - If not either, do I really have to implement all the intrinsic metafunctions listed in the MPL documentation or which ones would be sufficient? (The docs only says "many of intrinsic metafunctions offer a default implementation that will work in majority of cases", but it is not clear which ones exactly. And some tests with just providing begin and end did not lead me anywhere).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您不想将 std::tuple 转换为 mpl 类型,您可以重载标签调度 boost mpl 使用:
以及相关的测试:
我使用 gcc 4.7.2 和 clang 3.2 对此进行了测试。它应该包含使用 mpl 中的任何内容所需的一切(实际上比它需要的多一点)。您可以将元组视为 mpl::list (前向迭代器编译类型)。所以,为了让它发挥得更好,你应该实现 boost::mpl::list 的功能。快速浏览一下 boost/mpl/list/aux_ 目录:
begin_end.hppempty.hppiterator.hpppop_front.hpppush_back.hppsize.hpp
清除.hpp front.hpp push_front.hpp tag.hpp
是需要实施的相关文件。
If you wanted to not convert the std::tuple into a mpl type, you can overload the tag dispatching boost mpl uses:
And the associated test:
I tested this with gcc 4.7.2 and clang 3.2. It should contain everything you need to use anything in the mpl (actually a litte more than it needs). You can think of a tuple as a mpl::list (forward iterator compile type). So, to make it play nice you should implmenet what boost::mpl::list does. A quick look into the boost/mpl/list/aux_ directory:
begin_end.hpp empty.hpp iterator.hpp pop_front.hpp push_back.hpp size.hpp
clear.hpp front.hpp push_front.hpp tag.hpp
are the relevant files that need to be implemented.
从 std::tuple 转换为 boost 类型并返回似乎是最简单的方法
*测试过:
MacOSx 上的 boost_1_46_0 和 g++-4.5
Ubuntu 10.10 上的 boost_1_45_0 和 g++-4.5
Converting from std::tuple to boost types and back seems to be the easiest way
*tested with:
boost_1_46_0 and g++-4.5 on MacOSx
boost_1_45_0 and g++-4.5 on Ubuntu 10.10
这是我在 std::tuple 和 boost 类型之间进行转换的版本,但正如上面的评论中所述,转换可能在编译时效率不高,即会导致(不必要的)长编译时间。避免转换的解决方案肯定是首选......
This is my version for converting between std::tuple and boost types, but as said in the comment above, conversion probably is not very compile-time efficient, i.e., will result in (unnecessary) long compile times. A solution that avoids conversion surely would be preferred...