如何使用boost :: transformed在模板构造中使用lambda修改序列?

时间:2014-08-21 09:38:05

标签: c++ boost lambda

我有一个MyStruct类型,我想制作一些"序列" from,其中MyStruct的每个实例都是通过向其构造函数传递另一个范围的元素以及某个函数的输出而生成的。

函数本身(SomeFun)是另一个类中的成员函数,但是对于这个例子,我将使它成为一个自由函数。但是,请记住,我可以简单地将它放在lambda中或做其他棘手的事情以避免需要lambda,因为我确实需要在实际情况下实际传递this指针。

这是一个简化的可测试版本,用于说明我遇到的问题:

#include <iostream>                                                             
#include <vector>                                                               
#include <boost/range/adaptor/transformed.hpp>                                  

#include <functional>                                                           

template <typename RowType>                                                     
class MyStruct;                                                                 

template <typename T>                                                           
int SomeFun(T t)                                                                
{                                                                               
    return 0;                                                                   
}                                                                               

template <typename Sequence>                                                    
using Converter = std::function<                                                
    MyStruct<typename Sequence::value_type>(                                    
        typename Sequence::value_type&)>;                                       

template <typename Sequence>                                                    
boost::transformed_range<Converter<Sequence>, Sequence>                         
    GenerateTransformedRange(const Sequence& outputs)                           
{                                                                               
    std::function<MyStruct<typename Sequence::value_type>(int)> fun =           
        [](const typename Sequence::value_type output)                          
        {                                                                       
            return MyStruct<typename Sequence::value_type>(output, SomeFun(output));
        };                                                                      

    return outputs | boost::adaptors::transformed(fun);                         
}                                                                               

// some structure                                                               
template <typename T>                                                           
struct MyStruct                                                                 
{                                                                               
    MyStruct(T t, int a)                                                        
    {                                                                           
    }                                                                           
};                                                                              

int main(int argc, const char* argv[])                                          
{                                                                               
    std::vector<int> vec {1, 2, 3};                                             

    for (auto element : GenerateTransformedRange(vec))                          
    {                                                                           
    }                                                                           

    return 0;                                                                   
}

这个输出是:

  

main.cpp:31:54:错误:无法转换   'boost :: range_detail :: operator |(const InputRng&amp;,const   boost :: range_detail :: transform_holder&amp;)[使用InputRng   = std :: vector; UnaryFunction = std :: function(int)&gt;]((*(const   升压:: range_detail :: transform_holder(INT)&GT;

     
    

)(&amp; boost :: range_detail :: forwarder :: operator()(T)const [with T = std :: function(int)&gt ;; Holder =     升压:: range_detail :: transform_holder](标准::函数(INT)GT(((常量     std :: function(int)&gt; *)(&amp; fun)))))))'from     “增强:: range_detail :: transformed_range(INT)&gt;中     const std :: vector&gt;'来     “增强:: range_detail :: transformed_range(INT&安培;)&gt;中     std :: vector&gt;'          返回输出|提高::适配器::转化(乐趣);                                                           ^ makefile:25:目标的配方&#39; .obj / main.o&#39;失败

  

我在这里做错了什么?我不明白为什么要从这种类型转换。有任何想法吗?我使用Boost 1.55

1 个答案:

答案 0 :(得分:4)

错误:

  

test.cpp:29:20:错误:'operator |'不匹配(操作数类型是'const std :: vector'和'std :: function&gt;(int)&gt;')        返回输出|乐趣;

应该非常清楚。操作数operator|vector没有function。你的第二个操作数应该是一个实际定义操作符的boost适配器。可能是这样的:

return outputs | boost::adaptors::transformed(fun);

也在此代码中:

std::function<MyStruct<Sequence>(int)> fun =
        [](const typename Sequence::value_type output)
        {
            return MyStruct<typename Sequence::value_type>(output, SomeFun(output));
        };

根据类型声明,fun应返回MyStruct<Sequence>,但您的lambda会返回MyStruct<typename Sequence::value_type>。此外,如果lambda期望int,您可能不应该将参数类型硬编码为Sequence::value_type。您应该将fun声明为Converter<Sequence>类型。另外,修复lambda的参数类型和与Converter匹配的函数(注意引用)。