2

I try to understand why my code gives a compilation error. I've made a minimal example that keep same behaviour / architecture and error than the code in my project. The goal is to made a parallel evaluation of object in a vector.

template < class InputIterator, class OutputIterator > void evaluate( InputIterator first, InputIterator last, OutputIterator outfirst ) { while( first != last ) { *outfirst++ = (*first++) / 2 ; // only for the example } } template < int num_t = 4 > struct ParallelEvaluator { template< typename InputContainer , typename OutputContainer > static void eval(InputContainer const & src, OutputContainer & dst) { std::vector<std::thread> threads ; auto bg = src.begin() ; auto bg_r = dst.begin() ; for ( int i = 0 ; i < num_t ; i++ ) { threads.push_back(std::thread(evaluate<typename InputContainer::iterator,typename OutputContainer::iterator> ,bg,bg+4,bg_r)) ; bg = bg+4 ; bg_r = bg_r + 4 ; } std::for_each(threads.begin(),threads.end(),std::mem_fn(&std::thread::join)); } }; int main() { std::vector<int> t = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} ; std::vector<int> v(16) ; ParallelEvaluator<4>::eval(t,v) ; return 0; } 

When I try to compile this code I get the following error :

/usr/include/c++/4.8/functional:1697: error: no type named 'type' in 'class std::result_of<void (*(__gnu_cxx::__normal_iterator<const int*, std::vector<int> >, __gnu_cxx::__normal_iterator<const int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >))(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >)>' 

I saw that kind of error occurs when reference are using in the thread callback but it is not the case here.

Does somebody know why this error occurs ? Do I need a specific syntax to use template and co ?

Thanks

3
  • Which line produces the error? Commented Jun 27, 2014 at 14:54
  • @Angew the line in the loop for threads.push_back(...) Commented Jun 27, 2014 at 14:55
  • Interesting problem. I've looked at the full error on ideone and it seems the standard library is incapable of realising that evaluate<:::> is a function... Commented Jun 27, 2014 at 15:00

2 Answers 2

3

The type of bg is not std::vector<int>::iterator, it is std::vector<int>::const_iterator since src is a const&. Be lazy and let the compiler deduce the correct types with decltype. (Also, you could avoid some memory allocations by using std::array<std::thread,num_t> instead of std::vector<std::thread>.):

template< typename InputContainer , typename OutputContainer > static void eval(InputContainer const & src, OutputContainer & dst) { std::array<std::thread, num_t> threads ; auto bg = src.begin() ; auto bg_r = dst.begin() ; for ( int i = 0 ; i < num_t ; i++ ) { threads[i] = std::thread(evaluate<decltype(bg),decltype(bg_r)> ,bg,bg+4,bg_r)) ; bg = bg+4 ; bg_r = bg_r + 4 ; } std::for_each(threads.begin(),threads.end(),std::mem_fn(&std::thread::join)); } 

If you don't find lambdas offensive, threads[i] = std::thread([=]{ evaluate(bg,bg+4,bg_r); }); does the same thing with a bit less syntax.

Sign up to request clarification or add additional context in comments.

1 Comment

I just realised the same from the full error message, you beat me to writing it down. Have a +1 :-)
1

Your problem is that your types do not match -- you are passing const_iterators and explicitly expecting iterators, because you got the type you are expecting wrong, because template functions are annoying to pass around.

To fix this wrap your template funxtions you want to pass around into perfect forwarding override set functors:

struct evaluate_t { template<class...Args> void operator()(Args&&...args)const{ evaluate( std::forward<Args>(args)... ); }}; static evaluate_t evaluate_overrides; 

then pass evaluate_overrides to std::thread instead of evaluate<blah,blah>. Which override to use is now deferred to the point where it is called, instead of where you pass it in.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.