在boost :: mpl :: for_each()中调用泛型lambda

时间:2017-10-27 13:25:25

标签: c++ templates boost lambda boost-mpl

这里的一些答案(How to loop through a boost::mpl::list?是我开始的那个)意味着我应该能够构建一个通用的lambda来提供给boost :: mpl :: for_each()但是我无法找一个有效的例子,或者自己建一个。

想要在lambda中能够做的事情就是采用像

这样的函数
template<typename T>
void TestFunction(const int &p)
{
  T t(p);
  std::cout << "p = " << p << ", t = " << t << std::endl;
};

我正在调用一个类似

的循环
for(int k = 0; k < 2; ++k)
{
  TestFunction<int>(k);
  TestFunction<long>(k);
  TestFunction<float>(k);
  TestFunction<double>(k);
};

并将其替换为

typedef boost::mpl::list<int, long, float, double> ValidTypes;

for(int k = 0; k < 2; ++k)
{
  // lambda definition that captures k

  // boost::mpl::for_each(ValidTypes, ...) that calls the lambda.
};

这可能吗?如果没有for_each()与其他mpl结构之一?我有一个版本的代码运行,我重载operator()但我想看看lambda解决方案,如果可能的话。

谢谢,     安迪。

1 个答案:

答案 0 :(得分:0)

如果你可以使用C ++ 14的通用lambda,你可以捕获p的值,并推断传递给lambda的当前有效类型的类型:

#include <boost/mpl/for_each.hpp>
#include <boost/mpl/list.hpp>
#include <iostream>

int main() 
{
    using ValidTypes = boost::mpl::list<int, long, float, double>;

    for (auto k = 0; k < 2; ++k) {
        boost::mpl::for_each<ValidTypes>([p = k](auto arg) { 
            using T = decltype(arg);
            T t(p);
            std::cout << "p = " << p << ", t = " << t << '\n'; 
        });
    }
}

Live Example

修改:要获得额外的功劳,这里有一个稍微高级的版本,也适用于非默认的可构造类型:

#include <boost/mpl/for_each.hpp>
#include <boost/mpl/list.hpp>
#include <iostream>

class NonDefaultConstructible
{
    int value;
public:
    NonDefaultConstructible(int const& p) : value(p) {}

    friend auto& operator<<(std::ostream& ostr, NonDefaultConstructible const& ndc)
    {
        return ostr << ndc.value;
    }
};

int main() 
{
    using ValidTypes = boost::mpl::list<int, long, float, double, NonDefaultConstructible>;

    for (auto k = 0; k < 2; ++k) {
        boost::mpl::for_each<ValidTypes, boost::mpl::make_identity<boost::mpl::_1>>([p = k](auto arg) { 
            using T = typename decltype(arg)::type;
            T t(p);
            std::cout << "p = " << p << ", t = " << t << '\n'; 
        });
    }
}

Live Example

有关使用make_identity稍微复杂的解释,请在此处查看我的very first Q&A