2015-05-06 3 views
0

Я пытаюсь переписать java код с помощью c++. Я вообще не владею C++.передать тип объекта в std :: конструктор массива

Оригинал java код

public static <T, K> K[] toArray(ITemplateCommand<T, K> command, List<T> templates) { 
    if (null == templates) { 
     return null; 
    } 
    K[] array = (K[]) Array.newInstance(command.getClassOfK(), templates.size()); 
    for (int i = 0; i < templates.size(); i++) { 
     array[i] = command.buildTemplate(templates.get(i)); 
    } 
    return array; 
} 

Мой c++ код.

class TemplateImplementation { 

    public: 
     template<class K, class T> 
     static K* toArray(ITemplateCommand<T,K> *command, std::list<T>& templates) { 
      if (nullptr == templates) { 
       return nullptr; 
      } 
      std::array<command->getClassOfK(), templates.size()> arr; // no idea how to pass object type there 
      for(int i = 0; i < templates.size(); i++) { 
       arr[i] = command->buildTemplate(templates[i]); 
      } 
     } 
}; 

В java Я создал интерфейс и несколько осуществления, где getClassOfK возвращаемый класс из K объекта.

Здесь, чтобы упростить вещи, я решил не создавать творческие реализации, а только класс с методами virtual, которые служат как inteface.

template<class T, class K> 
class ITemplateCommand { 
public: 
    virtual K* buildTemplate(T* tmplate); 

    virtual std::type_info getClassOfK(); 
}; 

Но у меня есть несколько ошибок во время компиляции (я использую онлайн c++ компилятора)

sh-4.2# g++ -std=c++11 -o main *.cpp                                                   
main.cpp: In static member function 'static K* TemplateImplementation::toArray(ITemplateCommand<T, K>*, std::list<T>&)':                              
main.cpp:24:64: error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp, long unsigned int _Nm> struct std::array'                       
      std::array<command->getClassOfK(), templates.size()> arr; // no idea how to pass object type there                                
                   ^                                           
main.cpp:24:64: error: expected a type, got 'command->.getClassOfK()'                                          
main.cpp:24:69: error: invalid type in declaration before ';' token                                           
      std::array<command->getClassOfK(), templates.size()> arr; // no idea how to pass object type there                                
                    ^                                          
main.cpp:26:22: error: invalid types 'int[int]' for array subscript                                           
       arr[i] = command->buildTemplate(templates[i]);                              

Но мой главный вопрос заключается в как передать тип класса в конструктор станда :: массив с помощью зОму: : type_info? Или это невозможно с помощью этого объекта?

P.S. Кроме того, я знаю, что это не очень хорошая идея, чтобы возвращать указатели из функции, но я хочу, чтобы держать код как можно ближе к оригинальному

+0

Здесь происходит фундаментальное несоответствие. Шаблоны C++ основаны на специализации времени компиляции, поэтому вы не можете создать шаблон из значения времени выполнения. – user1937198

+0

Хм ... Так что нельзя переписать исходный код? – lapots

+0

Это, вам просто нужно понять C++. Начните с просмотра std :: vector и использования параметров шаблона C++. – user1937198

ответ

3

Есть три вещи неправильно с этой линией:

std::array<command->getClassOfK(), templates.size()> arr; 

Потребность шаблоном array класса для создания двух вещей: типа и константного выражения, которое можно конвертировать в size_t. Обе эти вещи должны быть доступны во время компиляции. templates.size() основан на количестве элементов в этом list по адресу времени выполнения, поэтому преобразование list<T> в std::array<K, N> невозможно. Вторая проблема заключается в том, что не является типом - это функция, которая возвращает объект - это совсем не то, что нужно array. Это более простая проблема, однако, вам нужно передать тип K, и у вас уже есть: это всего лишь K. Последняя проблема заключается в том, что вы хотите вернуть K*, а array<K,N> - не a K*.

Правильный способ написать этот код - использовать динамический контейнер. В частности, std::vector:

template<class K, class T> 
static std::vector<K*> toArray(ITemplateCommand<T,K> *command, std::list<T>& templates) { 
    std::vector<K*> vec; 
    vec.reserve(templates.size()); 
    for (T& tmpl : templates) { 
     vec.push_back(command->buildTemplate(tmpl)); 
    } 
    return vec; 
} 
+0

Hm. Поэтому решение с 'std :: array arr;' не будет работать? – lapots

+0

@ user1432980 № 'templates.size()' не является постоянным выражением, его можно оценить только во время выполнения. Вы * можете * просто вернуть простой массив ('K * arr = new K [templates.size()];'), но использование 'vector' является очень предпочтительным. – Barry

+0

О! Так что, если бы я исправил «размер», он мог бы сработать? Я имею в виду прохождение «K». – lapots

Смежные вопросы