我本以为以下内容会给出相同的结果:
namespace mpl = boost::mpl;
template<int from, int to>
struct
make_vector1
: mpl::copy<
mpl::range_c<int,from,to>,
mpl::inserter<
mpl::vector<>,
mpl::push_back<mpl::placeholders::_1,
mpl::placeholders::_2 // <- Copy int_ types
>
>
>
{};
template<int from, int to>
struct
make_vector2
: mpl::copy<
mpl::range_c<int,from,to>,
mpl::inserter<
mpl::vector<>,
mpl::push_back<mpl::placeholders::_1,
mpl::int_<mpl::placeholders::_2::value> // <- Alternative?
>
>
>
{};
但事实并非如此。
int
main (int ac, char **av)
{
typedef make_vector1<0,3>::type v1;
typedef make_vector2<0,3>::type v2;
//returns 0, as I would expect
std::cout<<"I1 = "<<mpl::at<v1,mpl::int_<0> >::type::value <<std::endl;
//returns 2, which has me stumpted.
std::cout<<"I2 = "<<mpl::at<v2,mpl::int_<0> >::type::value <<std::endl;
}
知道这里发生了什么吗?
我想使用第二种方法来构造Example
类型的mpl::向量,其中:
template<int i>
struct Example : mpl::int_<i>
{};
但我不能让它工作。
非常感谢
您得到一个2,因为_2上的::value被定义为2(占位符索引)。MPL没有在占位符上定义:,原因很明显,所以您不能直接这样做。
现在,正如您所注意到的,访问mpl::range_c中的一个元素已经为您提供了一个mpl::int_,因此无需尝试提取数值来将其放回。mpl序列上的迭代的抽象为您做这件事。
对于您的实际使用,您可以使用一个元函数来获取mpl::int_并返回您的Example。您必须了解,没有合适的通用元编程或元lambda函数可以用整型完成,因此mpl::int_ abstraction:
#include <boost/mpl/at.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/push_back.hpp>
namespace mpl = boost::mpl;
template<int I> struct Example : boost::mpl::int_<I>
{
static void foo() { std::cout << "**" << I << "**n";}
};
template<class T> struct make_example
{
typedef Example<T::value> type;
};
template<int from, int to>
struct
make_vector2
: mpl::copy<
mpl::range_c<int,from,to>,
mpl::inserter<
mpl::vector<>,
mpl::push_back<mpl::placeholders::_1,
make_example<mpl::placeholders::_2> // <- Alternative?
>
>
>
{};
int main(int ac, char **av)
{
typedef make_vector2<0,3>::type v2;
mpl::at<v2,mpl::int_<0> >::type::foo();
}
我添加了foo()只是为了评估我们在调用.后是否进入了正确的类类型
让我们回顾一下:
- 积分模板参数是不可靠的,这就是MPL使用int_的原因。每一个积分常数序列实际上都已经返回int_以保持抽象级别
- 占位符具有用于内部目的的::值,因此是您的初始结果
- 任何元函数都可以通过使用占位符进行实例化来转换为lambda