2

I want to pass the standardized C++ binary functions to a template function, but somehow I didn't get it to work.

The following is my attempt to do it:

template<template <typename> typename Pred,typename T, typename Iterator> void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep) { int currMaxThreads = startofSequence_; bool first = true; generate(begin, end, Pred<T>(currMaxThreads, threadStep) ); } 

and testing it with:

vector<int> tempVect_(10, 0); iota_stepa<std::plus>(begin(tempVect_),end(tempVect_),1,thread::hardware_concurrency()); 

gives me unfortunately the errors:

Severity Code Description Project File Line Suppression State Error C2440 '<function-style-cast>': cannot convert from 'initializer list' to 'std::plus<int>' Error C2672 'generate': no matching overloaded function found FractalCarpet Error C2780 'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided FractalCarpet 

The console output looks like the following:

1> c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(55): note: see reference to function template instantiation 'void iota_stepa<std::plus,int,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>>(Iterator,Iterator,T,T)' being compiled 1> with 1> [ 1> Iterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>, 1> T=int 1> ] 1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2672: 'generate': no matching overloaded function found 1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2780: 'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided 1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(1532): note: see declaration of 'std::generate' 

Could someone help me, how to solve this problem?

6
  • There's usually more useful information in the Output window than in the Error List. Commented Dec 15, 2016 at 13:47
  • 2
    how on Earth is T resolved as float if both startofSequence and threadStep are integral (int and unsigned int)? I can't quite reproduce it. As for the C2780 - your std::plus constructor seems wierd, why are you passing parameters to it? Commented Dec 15, 2016 at 13:50
  • 1
    Personally I would just make it a function parameter to iota_stepa and just give it a template type like Func. That way you can pass other "functions" like lambdas. Commented Dec 15, 2016 at 13:55
  • What are you expecting Pred<T>(currMaxThreads, threadStep) to generate? generate expects a function that takes no parameters and returns a value when called. You are going to have to pass something that behaves like that to it. Commented Dec 15, 2016 at 14:01
  • generate takes a function of no parameters which returns the "next" element. An instance of std::plus adds two numbers. You might get better help if you described the problem you're trying to solve rather than the problem you encountered while trying to solve it. Commented Dec 15, 2016 at 14:01

2 Answers 2

3

std::generate needs a generator, something that can be called like gen(). You could create one with a lambda, perhaps like this:

template<template <typename> class Pred, typename T, typename Iterator> void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep) { bool first = true; T current; auto gen = [&]() -> T { if(first) { current = startofSequence_; first = false; } else { current = Pred<T>() ( current, threadStep ); } return current; }; generate(begin, end, gen ); } 
Sign up to request clarification or add additional context in comments.

1 Comment

this solves the problem. Thank you! My intention was to generate a sweeping map like {128,256,512,...} so I can do a performance analysis with different threads in block on the GPU.
0
Pred<T>(currMaxThreads, threadStep) ); 

Pred<T> is a type. You need to construct an actual callable object:

Pred<T>()(currMaxThreads, threadStep) ); 

This however cannot be the last argument to std::generate. The latter requires a callable object with no arguments, presumably holding a state (otherwise a call to std::fill woud suffice). It is unclear how an arbitrary binary function could be adapted to fill this role.

5 Comments

Pred<T>()(currMaxThreads, threadStep) ); can't be right. That returns a value when generate expects a function object.
This is an educated guess. I cannot quite reproduce the error. Please post a minimal reproducible example.
@NathanOliver Viewed alone, the original line has a very specific error reflected in the error message, and the fixed line fixes that specific error. Whether the fixed line is suitable for a larger context, I don't know. Perhaps the original code has more than one bug
Yes the original code has more than one bug. The problem with your solution is it replaces one error message with another. Not down voting because you are showing what the correct syntax is if they wanted to call it but is not what thy actually need. They need to create a function object that takes nothing and returns a value every time it is called.
@NathanOliver I have added this info to the answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.