Передача функции std :: vector для любого типа в функцию - PullRequest
2 голосов
/ 29 октября 2009

Дано:

template<typename T> class A {  
  B b;
  std::vector<T> vec1;
  std::vector<T> vec2;
}

Я бы хотел, чтобы в B была функция-член, которая заполняла (), которая принимает ссылку на них на векторы и заполняет vec2 значениями T в зависимости от некоторой информации, содержащейся в b.
Одним из способов сделать это является перегрузка fill () для каждого возможного аргумента T:

fill(const std::vector<float>& a, std::vector<float>& b)

и так далее, но это будет означать много ненужного дублирования, поскольку операции одинаковы для всех возможных T. Внутри fill () я мог бы использовать vector :: value_type для расчетов, но я не знаю, как объявить это так, что он принимает все виды std :: vector. Очевидным способом было бы использовать бесплатную функцию с шаблонами. Есть ли более простой способ сделать это?

Ответы [ 4 ]

5 голосов
/ 29 октября 2009

Вы получили несколько ответов, но я должен с ними не согласиться, по крайней мере, до некоторой степени. Моя немедленная реакция заключается в том, что вы не должны передавать вектор на b::fill вообще. Скорее, вы должны передать итератор (или, может быть, пару итераторов). Остальное в основном верно, хотя это означает, что fill должна быть функцией-членом шаблона. Когда вы вызываете его, вы, вероятно, захотите передать std::back_insert_iterator, обычно получаемый с std::back_inserter.

Часть того, что вы сказали, кажется противоречивой: если b::fill изменяет vec1 и vec2, они, вероятно, должны не быть переданы как ссылки на const. По общему признанию, const не имеет точно своего обычного значения применительно к контейнеру, но факт остается фактом: передача ссылки на const в функцию, единственное намерение которой, очевидно, состоит в том, чтобы изменить то, что было передано, кажется неправильной.

5 голосов
/ 29 октября 2009

Templatize B.

template<typename T> class B {
  void fill(const std::vector<T>& a, std::vector<T>& b) { }
};

template<typename T> class A {  
  B<T> b;
  std::vector<T> vec1;
  std::vector<T> vec2;
}

Если вы не хотите шаблонизировать B, шаблонизируйте функцию заполнения:

class B {
  template<typename T>
  void fill(const std::vector<T>& a, std::vector<T>& b) {}
};
4 голосов
/ 29 октября 2009

Templatize fill:

class B {
public:
  template<typename T>
  void fill(const std::vector<T>& a, std::vector<T>& b)
  { /*...*/ }
  //...
};

(Из вашего описания видно, что b должно быть const std::vector<T>&.)

2 голосов
/ 29 октября 2009

Вы можете определить B как класс шаблона, заполнить как функцию шаблона (внутри не шаблонного класса B) или, мой любимый, использовать стандарт std::transform / std::copy / std::fill, который уже является функцией шаблона, заполнить ваш вектор.
(Все находится внутри <algorithm> заголовка).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...