How do I use boost :: transform to change sequence using lambda in template construction?

I have a type MyStruct

from which I would like to create some "sequence" from which each instance is MyStruct

generated from passing it to the constructor of an element of a different range as well as the output of some function.

The ( SomeFun

) function itself is a member function of another class, but for this example I'll make it free. However, keep in mind that I might just put it inside the lambda, or do other tricky things to avoid the need for the lambda, because I really need to pass a pointer this

in my actual case.

Here's a simplified, testable version to illustrate the problem I'm having:

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

      

Way out of this:

main.cpp: 31: 54: error: failed to convert 'Boost :: range_detail :: operator | (const InputRng &, const boost :: range_detail :: transform_holder &) [with InputRng = std :: vector; UnaryFunction = std :: function (int)>] ((* (const boost :: range_detail :: transform_holder (INT)>

) (& boost :: range_detail :: forwarder :: operator () (T) const [with T = std :: function (int)>; Holder = boost :: range_detail :: transform_holder] (std :: function (intermediate) > (((const std :: function (int)> *) (& fun))))))) from "Upgrade :: range_detail :: transformed_range (intermediate)>, const std :: vector> to" Upgrade :: range_detail :: transformed_range (Int &)>, std :: vector> reverse outputs | boost :: adapters :: converted (fun); ^ makefile: 25: recipe for target .obj / main.o 'failed

What am I doing wrong here? I don't understand why he wants to convert from this type. Any ideas? I am using Boost 1.55

.

0


source to share


1 answer


Mistake:

test.cpp: 29: 20: error: no match for operator | (operand types: 'const std :: vector and' std :: function> (int)>) return outputs | fun;

should be perfectly clear. For operands vector

and a, function

no operator|

. Your second operand should be a boost adapter that actually defines the operator. Probably like this:

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

      



Also in this code:

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

      

As per the type declaration fun

should return MyStruct<Sequence>

, but your lambda returns a MyStruct<typename Sequence::value_type>

. Also, you probably shouldn't hardcode the type of the parameter as int

if the lambda expects Sequence::value_type

. You should probably declare fun

as a type Converter<Sequence>

. Also, correct the type of the lambda parameter and the function to match Converter

(note the link).

+3


source







All Articles