2015-05-29 1 views
4

Что касается кода ниже:Могу ли я использовать динамический массив как имя шаблона C++?

template<typename PatternType> 
cl_int enqueueFillBuffer(
    const Buffer& buffer, 
    PatternType pattern, 
    ::size_t offset, 
    ::size_t size, 
    const VECTOR_CLASS<Event>* events = NULL, 
    Event* event = NULL) const 
{ 
    cl_event tmp; 
    cl_int err = detail::errHandler(
     ::clEnqueueFillBuffer(
      object_, 
      buffer(), 
      static_cast<void*>(&pattern), 
      sizeof(PatternType), 
      offset, 
      size, 
      (events != NULL) ? (cl_uint) events->size() : 0, 
      (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, 
      (event != NULL) ? &tmp : NULL), 
      __ENQUEUE_FILL_BUFFER_ERR); 

    if (event != NULL && err == CL_SUCCESS) 
     *event = tmp; 

    return err; 
} 

Код может быть скомпилированного, если длина массива, , является статическим обозначена.

queue.enqueueFillBuffer<float[6]>(buffer, nodes, 2345, 123456); 

Мой вопрос заключается в том, как сделать длину, 6, переменной и передать компиляцию? Поскольку динамический массив поддерживается в C99, sizeof (float [n]) может правильно получить размер (для кода sizeof (PatternType)). Но я не могу сделать код ниже передать сборник:

int n = 6; 
queue.enqueueFillBuffer<float[n]>(buffer, nodes, 2345, 123456); 
+5

'n' не является постоянной времени компиляции, поэтому компилятор не может выводить статический тип массива во время компиляции. –

+1

Было бы неплохо сократить фрагмент кода до минимума, необходимого для понимания вашего вопроса. Для вашего примера вы можете предоставить пустую функцию. Это действительно так! – Klaus

+0

Да, компилятор не может вывести статический массив, но почему он не может распоряжаться им путем динамического массива. –

ответ

2

Рассмотрим с помощью std::array. В более общем плане предположим, что STL-подобный контейнер будет передан вашему методу. Так, например,

std::array<float, 6> nodes; 
nodes[0] = ... 

или

std::vector<float> nodes; 
nodes.resize(6); 
nodes[0] = ... 

Тогда линии

static_cast<void*>(&pattern), 
sizeof(PatternType), 

может быть заменен

static_cast<void*>(pattern.data()), 
sizeof(typename PatternType::value_type) * pattern.size(), 

Затем компилятор может вывести тип, поэтому при вызове метод тогда просто становится

queue.enqueueFillBuffer(buffer, nodes, 2345, 123456); 

Нет необходимости в явных аргументах шаблона.

+0

О нет. Код "static_cast (& pattern), sizeof (PatternType)" не может быть изменен. Это из файла заголовка OpenCL 1.2 C++ Wrapper. Это только ключ к проблеме. Я думаю, что это дефект дизайна. Я не знаю, может ли член группы Khronos увидеть это. –

+0

А я вижу. Я предполагаю [вы используете этот файл заголовка] (https://www.khronos.org/registry/cl/api/1.2/cl.hpp). Вы можете разветвить и изменить его, иначе я не вижу решения. – rwols

+0

Майк, динамический массив в этом случае, конечно, недействителен, потому что компилятор не смог определить размер аргумента шаблона. Я видел вашу отправку ошибок в Khronos, но если вы внимательно прочитаете спецификацию OpenCL, вы заметите, что тип шаблона должен быть одним из встроенных типов: «Шаблон данных должен быть скалярным или векторным целым или с плавающей запятой тип, поддерживаемый OpenCL, как описано в разделах 6.1.1 и 6.1.2. ".В то время как результат должен быть таким же, действительно недействительно передавать массив, как вы пытаетесь сделать. – Lee

0

Ответ не в том, чтобы закончить его. Что касается реализации enqueueFillBuffer, обратитесь к: https://www.khronos.org/bugzilla/show_bug.cgi?id=1347 Максимальный размер поддерживаемого шаблона - ulong16, 128 байт.