2013-09-23 5 views
0

Мой вопрос/проблема касается параметра функции, который будет использоваться в std::transform().std :: transform() прохождение ссылки в функциональном параметре

В следующих кодах, если я использовал «пройти по ссылке» в параметре целочисленного i от квадрата функции (т.е. int squared(int i)), он не компилируется.

Я должен изменить его пройти мимо значение так, что он собирает. Может кто-нибудь пожалуйста, скажите мне, почему и если это cosntraint для использования std::transform()?

std::for_each() прекрасно с использованием как «передача по значению» и «пройти по ссылке» подходы (как показано в print()).

Заранее спасибо.

#include <iostream> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

int squared(int i); 
void print(int &i); 


int main() 
{ 
    std::vector<int> intVec; 
    std::vector<int> newIntVec; 

    for (int i = 0; i < 10; ++i) 
     intVec.push_back(i); 

    std::for_each(intVec.begin(), intVec.end(), print); 
    std::cout << std::endl; 

    std::transform(intVec.begin(), intVec.end(), std::back_inserter(newIntVec), squared); 
    std::for_each(newIntVec.begin(), newIntVec.end(), print); 
    std::cout << std::endl; 

    return 0; 

} 

int squared(int i) 
{ 
    return i*i; 
} 

void print(int &i) 
{ 
    std::cout << i << " "; 
} 
+4

Не имеет значения, и это [работает для меня.] (Http://coliru.stacked-crooked.com/a/6416cd90fdbf444d). Какую ошибку вы получаете? – jrok

+0

Во втором абзаце вашего вопроса вы говорите о передаче по ссылке, т. Е. 'Int square (int)' ... но это не проходит по ссылке. Вы имеете в виду 'int squared (int &)'? ** Просьба описать конкретную проблему и предоставить действительный код для ее воспроизведения. ** Код, который вы предоставили, компилируется отлично, и вы не описали какую-либо ошибку компиляции. Голосование закрывается. –

+0

@JonathanWakely Да, приведенные выше коды компилируются правильно. Если вы измените прототип (и определение) функции на использование «передачи по ссылке», вы увидите ошибку компиляции. – Roy

ответ

4

Для std::transform, оператор не должен иметь никаких побочных эффектов (она должна принимать входные данные и обеспечить выход). Таким образом, вы должны попробовать сделать эталонную ПОСТОЯННОЕ:

int squared(const int &i) 
{ 
    return i*i; 
} 

цитату из CPP Reference «[функция] не должна иметь побочные эффекты» (C++), а также «[функции] не должен привести к недействительности итераторов, включая конечные итераторы, или изменить любые элементы используемых диапазонов. " (C++ 11)

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

С другой стороны, std::for_each работает с последовательностью данных, которые вы передаете, что означает, что значения могут быть изменены.

+0

Это объясняет, почему семантика предполагает, что вы используете 'const int & i', но не объясняет, почему это ошибка компилятора, если вы используете' int & i'. Кроме того, два кавычки, которые вы предоставляете с сайта, называя себя ссылкой CPP, фактически ссылаются на две разные версии стандарта C++ (как отмечает сам сайт). (Ясно, что первое, более раннее ограничение подразумевает второе, существующее, но оно слишком ограничительное.) – rici

+0

@rici: действительно, я пробовал код OP на пароле компиляторов, и, похоже, он работал, но решил, эффекты ". Что касается двух кавычек, ссылающихся на разные версии C++, это правда, но неясно, какая версия использует OP. Я немного обновлю ответ. – icabod

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