在 boost::mpl::for_each() 中调用通用 lambda

Calling a generic lambda in boost::mpl::for_each()

本文关键字:调用 lambda each mpl boost for      更新时间:2023-10-16

这里有一些答案(如何遍历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 解决方案。

谢谢 安 迪。

如果您可以使用 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'; 
        });
    }
}

活生生的例子

编辑:为了获得额外的信用,这里有一个稍微高级的版本,也适用于非默认的可构造类型:

#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'; 
        });
    }
}

活生生的例子

有关make_identity使用有点复杂的解释,请参阅我的第一个问答