2013-03-15 2 views
0

Может кто-нибудь, пожалуйста, помогите мне понять следующий синтаксис:Что означает «x (y) = z (w)» в C++?

aaa<bbb> object_name; 
func(object_name, object_name2); 
ccc<ddd>(object_name) = func2(arg1, arg2); 

Я понимаю, что в первом мы объявляем новый объект aaa<bbb> класса. Затем мы используем этот объект вместе с другим, чтобы вызвать функцию, которая, возможно, изменит значение object_name. У меня есть проблемы, чтобы понять третью строку. В частности, конструкция с левой стороны знака =. Почему в скобках стоит object_name? Для меня это похоже на функцию. Но может быть, мы называем функцию слева и справа от знака =?

+0

@ Carl Norum, но что тогда 'value1 = value2' конструкция делает? – Roman

+1

Поиск lvalue и ссылки в вашем учебнике на C++. – WhozCraig

ответ

5

Функциональный вызов может возвращать lvalue, который является типом, который может заметно отображаться в левой части выражения присваивания. Обычной категорией lvalue в этом случае является ссылка; например vector<T>::front возвращает ссылку типа T &:

std::vector<int> v{0, 1, 2, 3}; 
v.front() = 99; 
// v is now {99, 1, 2, 3} 

Расширенное использование только: это также возможно для функции вернуть prvalue объектного типа с перегруженным оператором присваивания, так что выражение присваивания имеет некоторый соответствующий эффект; однако стандартная библиотека не использует это, за исключением нескольких случаев, таких как ostream_iterator.

+0

Я почти понял концепцию. Единственная проблема, которая у меня есть, это концепция или ссылка. Я понимаю это как «адрес памяти» переменной. Но, насколько я помню, если 'a' является адресом переменной, мы можем изменить значение переменной с помощью' * '. Например, '* a = 5'. Итак, почему мы не используем '*' в этом случае? '* (v.front()) = 99;' – Roman

+0

@Roman Оператор '*' предназначен для использования с * указателями *, которые инкапсулируют адрес памяти объекта и могут быть косвенными (с использованием '*' унарного оператора) для получения lvalue для этого объекта. Ссылки ведут себя как lvalue для объекта, на который они ссылаются на протяжении всего жизненного цикла ссылки, без необходимости направления. – ecatmur

0

Я думаю, что левая часть третьего создает экземпляр функции шаблона с аргументом * object_name *. Что можно присвоить значение func2() может быть связано с некоторой перегрузкой оператора =?

0

ccc<ddd>, вероятно, является функцией (специализация шаблона функции). Он может вернуть ссылку, и в этом случае объект, на который ссылается, будет изменен. Или он может вернуть объект «прокси», который имеет operator=, который сделает что-то полезное.

Менее вероятно, ccc<ddd> может быть типом класса (специализация шаблона класса). Но для того, чтобы иметь в виду что-нибудь полезное, его operator= должен был иметь какой-то побочный эффект, отличный от временного объекта ccc<ddd>, что было бы странно.

1

Возможно, возвращаемое значение является значением l, которым вы действительно можете присвоить значение. Это может быть примерно так:

int x = 5; 

template <typename T> 
int& foo() { return x; } 

void test() 
{ 
    foo<long>() = 10; 
} 
+0

У меня мало вопросов о нашем примере. Почему вы используете шаблоны? Для меня это похоже на то, что вы «объявляете» тип 'T' перед функцией' foo', но позже вы не используете этот тип? Итак, в чем была причина заявить об этом?Во-вторых, что возвращает функция 'foo'? Очевидно, что это не x, иначе мы имели бы '5 = 10'. Возвращает ли он адрес переменной 'x'. Если да, то почему мы не используем '*' для изменения значения, расположенного по этому адресу: '* foo () = 10;'? – Roman

+0

Причина была предназначена только для того, чтобы привести пример, аналогичный тому, который вы предоставили. Конечно, в вашем примере шаблон будет использоваться как-то, но поскольку нет реализации, я не могу придумать, как это сделать. Он возвращает ссылку, которая является адресом переменной, но она предназначена для использования по-другому. Реализация мудрая, это указатель, но у него разные ограничения, http://en.wikipedia.org/wiki/Reference_(C%2B%2B) – Jack

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