2017-02-16 8 views
2

Я не мог понять, почему мой код не работает. У меня есть два вектора, и я хочу, чтобы заменить мой второй вектор с произведением каждого элемента (v2[0] = v1[0] * v2[0], v2[1] = v1[1] * v2[1] и так далее ...)элемент мудрый вектор умножения C++ (код не работает)

код

vector <float> vectorMultiplication(vector <float> &v1, vector <float> &v2) 
{ 
    return std::transform(v1.begin(), v1.end(), v2.begin(), std::multiplies<float>()); 
} 

Если кто-то может указать на то, что я ошибка, я буду очень благодарен.

P.S. Сообщение об ошибке, которое генерирует мой компилятор: error: conversion from ‘__gnu_cxx::__normal_iterator<float*, std::vector<float> >’ to non-scalar type ‘std::vector<float>’ requested P.S. 2 Я запускаю C++ 98

+4

подсказка: что возвращаемый тип 'станд :: transform'? Каков тип возврата вашей функции? Я знаю, что это трудно поверить, но иногда rtfm действительно помогает – user463035818

+3

'std :: transform' не возвращает контейнер. –

ответ

6

Ошибка довольно ясна: std::transform returns an iterator, вы возвращаете vector<float>, который не может быть неявно построен одним итератором.


Кроме того, перегрузка std::transform, что вы пытаетесь назвать не правильным, так как она принимает UnaryOperation в то время как std::multiplies является BinaryOperation. Вам нужна эта перегрузка:

template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation > 
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, 
        OutputIt d_first, BinaryOperation binary_op); 

Следующий код будет компилироваться и работать:

auto vectorMultiplication(const std::vector<float>& v1, const std::vector<float>& v2) 
{ 
    std::vector<float> result; 
    std::transform(v1.begin(), v1.end(), v2.begin(), 
        std::back_inserter(result), std::multiplies<float>()); 
    return result; 
} 

coliru example


Пример использования:

std::vector<float> v1 = {1, 2, 3, 4}; 
std::vector<float> v2 = {1, 2, 3, 4}; 

auto vm = vectorMultiplication(v1, v2); 
for(const auto& x : vm) std::cout << x << " "; 

Напечатает:

+1

Почему бы просто не сделать это функцией пустоты? – NathanOliver

+0

однако он все еще терпит неудачу на 'std :: mulitplies': http://coliru.stacked-crooked.com/a/f3de8a67d82cc70a Любое предположение? – pergy

+0

@pergy: Я не смотрел на код достаточно тщательно. Необходимо вызвать другую форму 'std :: transform' ... (исправление) –

0

Ошибка в том, что return std::transform(...); пытается вернуть результирующий выходной итератор, но ваша функция объявлена ​​вернуться vector<float>. Вам нужно решить, что вы на самом деле хотите вернуть, потому что здесь не совсем ясно. Может быть, просто void, и полностью удалить ключевое слово return?

Но вы действительно хотите применить функцию к элементу от v1 и к элементу v2 в то же время. Форма transform, которую вы пытаетесь использовать, не делает этого. Существует еще одна форма, что делает, но это будет немного запутанным здесь:

std::transform(v1.begin(), // start of first input range 
       v1.end(), // end of first input range 
       v2.begin(), // start of **second input** range 
       v2.begin(), // start of **output** range 
       std::multiplies<float>()); 

См version 3 here.

Для этого вы должны быть уверены, что v1.size() <= v2.size().

Click here for a working example.

0

Проблема очевидна из сообщения об ошибке компилятора. Возвращаемый тип std::transform является итератором, а не контейнером.

Вызов

std::transform(v1.begin(), v1.end(), v2.begin(), std::multiplies<float>()); 

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

Вы можете изменить возвращаемое значение функции void:

void vectorMultiplication(vector <float> &v1, vector <float> &v2) 
{ 
    std::transform(v1.begin(), v1.end(), v2.begin(), std::multiplies<float>()); 
} 

или вернуть v2:

vector <float> vectorMultiplication(vector <float> &v1, vector <float> &v2) 
{ 
    std::transform(v1.begin(), v1.end(), v2.begin(), std::multiplies<float>()); 
    return v2; 
}