ошибка: для использования шаблона класса ‘blocked_range’ требуются аргументы шаблона

#c #tbb

#c #tbb

Вопрос:

Я использую библиотеку TBB следующим образом:

 // 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> amp;range, Fn amp;amp;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 amp;amp;fn, size_t granularity = 1)
{
    tbb::parallel_for(tbb::blocked_range{from, to, granularity}, // => Error happens at this line
                      [amp;fn, from](const auto amp;range) {
        loop_(range, std::forward<Fn>(fn));
    });
}
  

Я получаю эту ошибку:

Параллелизм.hpp:43:32: ошибка: использование шаблона класса ‘blocked_range’ требует аргументов шаблона blocked_range.h:45:7: примечание: здесь объявлен шаблон

Кто-нибудь сталкивался с этой ошибкой раньше? Как это решить?

Комментарии:

1. Вы компилируете в режиме C 17 или более поздней версии?

2. @aschepler Нет! Я думаю, что C 11 или C 14…

3. @user3405291 Сообщение об ошибке достаточно четкое. В чем проблема? Вы не можете прочитать сообщение?

4. @VladfromMoscow Код взят из репозитория, который отлично компилируется другими. Поэтому код должен быть правильным!

5. @user3405291 Тогда, похоже, ваша проблема заключается в использовании неправильной версии C .

Ответ №1:

tbb::blocked_range это шаблон класса, и вы пытаетесь использовать вывод аргументов шаблона класса (CTAD), опуская любые явные аргументы шаблона при его создании.

 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 является функцией C 17, поэтому, если вы компилируете с более ранней языковой версией, вам нужно будет указать Value аргумент шаблона типа для шаблона tbb::blocked_range класса. Из приведенного выше мы видим, что Value тип ожидается как тип итератора, в частности, тип первых двух аргументов, переданных его конструктору, from и to в на сайте вызова. Таким образом, вы можете изменить свой фрагмент следующим образом:

 // Calling TBB parallel-for by this template
template<class It, class Fn>
static void for_each(It from, It to, Fn amp;amp;fn, size_t granularity = 1)
{
    tbb::parallel_for(tbb::blocked_range<It>{from, to, granularity},
                      [amp;fn, from](const auto amp;range) {
        loop_(range, std::forward<Fn>(fn));
    });
}
  

Из того, что вы упомянули в своих комментариях, это может быть проблемой переносимости, и после этого вы, вероятно, столкнетесь с новыми проблемами и, возможно, захотите просмотреть флаги компиляции вашего проекта, чтобы узнать, можете ли вы скомпилировать с использованием C 17 вместо этого.

Ответ №2:

Ошибка гласит 'blocked_range' requires template arguments .

Одним из решений является добавление некоторых аргументов шаблона. Я понятия не имею, какими они должны быть, но, возможно

 tbb::blocked_range<I>{from, to, granularity}
                  ^^^
                  template argument here