- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello. I've got next problem with using parallel_do: it even fails to compile if i pass std::bind result:
In file included from D:\Projects\MyProject\src\server.cpp:4:0:
D:/libs/tbb43_20150209/include/tbb/parallel_do.h: In instantiation of 'void tbb::parallel_do(Iterator, Iterator, const Body&) [with Iterator = long long unsigned int; Body = std::_Bind<void (*(std::_Placeholder<1>))(int&)>]':
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:492:74: required from 'void tbb::parallel_do(const Range&, const Body&) [with Range = tbb::blocked_range<long long unsigned int>; Body = std::_Bind<void (*(std::_Placeholder<1>))(int&)>]'
D:\Projects\MyProject\src\server.cpp:50:71: required from here
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:482:9: error: no matching function for call to 'select_parallel_do(long long unsigned int&, long long unsigned int&, const std::_Bind<void (*(std::_Placeholder<1>))(int&)>&, <unresolved overloaded function type>, tbb::task_group_context&)'
);
^
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:482:9: note: candidates are:
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:412:10: note: template<class Iterator, class Body, class Item> void tbb::internal::select_parallel_do(Iterator, Iterator, const Body&, void (Body::*)(Item) const, tbb::task_group_context&)
void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const
^
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:412:10: note: template argument deduction/substitution failed:
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:482:9: note: couldn't deduce template parameter 'Item'
);
^
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:429:10: note: template<class Iterator, class Body, class Item, class _Item> void tbb::internal::select_parallel_do(Iterator, Iterator, const Body&, void (Body::*)(Item, tbb::parallel_do_feeder<_Item>&) const, tbb::task_group_context&)
void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const
^
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:429:10: note: template argument deduction/substitution failed:
D:/libs/tbb43_20150209/include/tbb/parallel_do.h:482:9: note: couldn't deduce template parameter 'Item'
);
That's what my code do:
void print_item(int32_t& value) { //I know using iostreams like that is not thread safe i was just testing std::cout << "value: " << value << std::endl; } int main(int argc, char** argv) { std::vector<int32_t> test; for(int i = 1; i <= 100; ++i) { test.push_back(i); } auto print_value = std::bind(&print_item,std::placeholders::_1); //this have special type _Bind
std::function<void(int32_t&)> print_value_function = std::bind(&print_item,std::placeholders::_1); //this have special type _Bind
tbb::parallel_do(test,print_value); //fails to compile
tbb::parallel_do(test,print_value_function ); //compiles fine
}
Of course i can wrap those into std::function but that would add unnesessary overhead. Also i've found a problem in code using automatic argument type deduction in this code(and also in another places where it used):
//! For internal use only. /** Detects types of Body's operator function arguments. @ingroup algorithms **/ template<typename Iterator, typename Body, typename Item> void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context #endif // __TBB_TASK_GROUP_CONTEXT ) { run_parallel_do<Iterator, Body, typename strip<Item>::type>( first, last, body #if __TBB_TASK_GROUP_CONTEXT , context #endif // __TBB_TASK_GROUP_CONTEXT ); } //! For internal use only. /** Detects types of Body's operator function arguments. @ingroup algorithms **/ template<typename Iterator, typename Body, typename Item, typename _Item> void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context #endif // __TBB_TASK_GROUP_CONTEXT ) { run_parallel_do<Iterator, Body, typename strip<Item>::type>( first, last, body #if __TBB_TASK_GROUP_CONTEXT , context #endif // __TBB_TASK_GROUP_CONTEXT ); }
I tried to use functional object where operator() is inherited from base class and Body type is different so that code fails to compile
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What overhead are you concerned about: performance-wise (presumed or measured?) or just syntactical? For the latter, it's probably doable (no pun intended) to use std::is_bind_expression to differentiate and std::function (from what you've found) to pick up operator(), and then maybe something more efficient if still desirable, but I haven't tried anything yet.
Did you use the keyword "override" for the overridden operator()? It might have alerted you about declaring the operator as "const". Only the "const" is required, though.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page