I'm using TBB library like this:
// Concurrency.hpp
#include <tbb/spin_mutex.h>
#include <tbb/mutex.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
// Restrict templates to work for only the specified set of types
template<class T, class O = T>
using IntegerOnly = std::enable_if_t<std::is_integral<T>::value, O>;
// An extra helper template
template<class Fn, class I>
static IntegerOnly<I, void> loop_(const tbb::blocked_range<I> &range, Fn &&fn)
{
for (I i = range.begin(); i < range.end(); ++i) fn(i);
}
// Calling TBB parallel-for by this template
template<class It, class Fn>
static void for_each(It from, It to, Fn &&fn, size_t granularity = 1)
{
tbb::parallel_for(tbb::blocked_range{from, to, granularity}, // => Error happens at this line
[&fn, from](const auto &range) {
loop_(range, std::forward<Fn>(fn));
});
}
I'm receiving this error:
Concurrency.hpp:43:32: error: use of class template 'blocked_range' requires template arguments blocked_range.h:45:7: note: template is declared here
Did anybody run into this error before? How to resolve it?
tbb::blocked_range
is a class template, and you are attempting to use class template argument deduction (CTAD) by omitting any explicit template arguments when constructing it.
template<typename Value> class blocked_range { public: //! Type of a value /** Called a const_iterator for sake of algorithms that need to treat a blocked_range as an STL container. */ typedef Value const_iterator; // ... //! Construct range over half-open interval [begin,end), with the given grainsize. blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) // ... // ... };
CTAD, however, is a C++17 feature, so if you are compiling with an earlier language version, you will need to specify the Value
type template argument for the tbb::blocked_range
class template. From above, we see that the Value
type is expected as the iterator type, specifically the type of the first two arguments passed to its constructor, from
and to
in at the call site. Thus, you may modify your snippet as follows:
// Calling TBB parallel-for by this template
template<class It, class Fn>
static void for_each(It from, It to, Fn &&fn, size_t granularity = 1)
{
tbb::parallel_for(tbb::blocked_range<It>{from, to, granularity},
[&fn, from](const auto &range) {
loop_(range, std::forward<Fn>(fn));
});
}
From what you mention in your comments this may be a portability issue, and you may be likely to run into more issues after this one, and may want to consider looking over your project's compilation flags, so to see if you could possibly compile using C++17 instead.