【问题标题】:Calling a generic lambda in boost::mpl::for_each()在 boost::mpl::for_each() 中调用通用 lambda
【发布时间】:2017-10-27 13:25:24
【问题描述】:

这里的一些答案(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 解决方案。

谢谢, 安迪。

【问题讨论】:

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


    【解决方案1】:

    如果您可以使用 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

    【讨论】:

    • 谢谢@TemplateRex! make_identity 技巧是我尝试中缺少的链接!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多