Ошибка c2106 левый операнд должен быть левосторонним значением

The message says that you try to assign to an expression which is not an lvalue. For built-in types, you can only assign to lvalues (that’s where the name comes from: lvalue = value that can be on the left hand side of the assignment operator, while rvalue = value that must be on the right hand side of the assignment operator).

So what is an lvalue or an rvalue? Consider the following code:

int a;
a = 3;

In this assignment a is an lvalue (if it weren’t, the compiler would complain). That is, the expression a refers to an object which can be modified. On the other hand, 3 is an rvalue, that is, basically a value. Of course you cannot assign to 3; the compiler would complain about the statement 3=a; with exactly the same message you got in your code.

So as a first approximation, an lvalue designates an object, while an rvalue designates a value. Note that this is also true for assignment of the form

a = b;

where b also is a variable. What happens here is the so-called lvalue to rvalue conversion: What is assigned is not the object b, but its current value.

Now consider the following case:

int f();
f() = 3;

Here you might argue that the function f does return an object (if you use some user-defined type, you even can see its construction/destruction). But the compiler still complains with the message you got. Why?

Well, even if you consider f to return an object, it is a temporary object which will go away immediately. So it does not make much sense to assign a value because you cannot do anything with it anyway afterwards.

Therefore here’s the second rule:

Whenever there’s an expression which produces a temporary object, C++ defines that expression as rvalue.

And now we come to the definition of MyVector::at() which you did not show, but which, according to the error message, probably looks similar to this:

template<typename T>
 T MyVector<T>::at(int i)
{
  return data[i];
}

This has essentially the same form as f above, as it also returns a T (an employee* in your case). This is why the compiler complains.

And that complaint is helpful: Even if the compiler wouldn’t complain, the code would not dio what you almost certainly intended. The return statement returns a copy of the object data[i]. Thus if the statement payment.at(i)=NULL; had compiled, what would actually happen would be the following:

  1. The internal object data[i] (or however you called it in your code) is copied and the temporary copy returned.
  2. The statement assigned that temporary copy, but leaves the original object in MyVector unchanged.
  3. The temporary copy gets destructed, leaving no trace of your assignment.

This is almost certainly not what you wanted. You wanted to change the internal object. To do so, you have to return a reference to that object. A reference refers to the object it was initialized with instead of making a copy. Correspondingly, a reference, even when returned, is an lvalue (since C++11 there’s a second type of reference which behaves differently, but we don’t need to care about that here). Your corrected function then reads

template<typename T>
 T& MyVector<T>::at(int i)
{
  return data[i];
}

and with that definition, payment.at(i)=NULL; not only compiles, but actually does what you want: Change the internally stored i-th pointer in payment to NULL.

BoBaH26

30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

1

20.09.2011, 23:20. Показов 9169. Ответов 39

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте, при попытке символьному элементу структуры (char name [30]) присвоить такой же символьный элемент выдается ошибка C2106 — левый операнд должен быть левосторонним значением. Вот фрагмент листинга, на всякий случай с описанием самой структуры:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
..........
struct List {
        int shifr;
        char name [30];
        int kol;
        float stoim;
    };
List MasList [100],min;
..........
..........
min.shifr=MasList[i].shifr;
        min.name=MasList[i].name; //<------ Эта строка.
        min.kol=MasList[i].kol;
        min.stoim=MasList[i].stoim;

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



0



794 / 546 / 61

Регистрация: 11.05.2010

Сообщений: 1,298

Записей в блоге: 1

20.09.2011, 23:37

2

BoBaH26, массивы массивам не присваиваются. Для копирования строк используйте strcpy.



0



186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:38

3

name — это указатель на строку.
Вы присваиваете указателю указатель, а указатель min.name является константным, т.е. его нельзя изменить.



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:39

 [ТС]

4

Сейчас попробую…



0



talis

20.09.2011, 23:40

Не по теме:

Chelioss, это не указатель. Массив чистой воды

Цитата
Сообщение от BoBaH26
Посмотреть сообщение

char name [30];



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:41

 [ТС]

6

Chelioss, так а как тогда? Через copy, как сказал talis?



0



186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:41

7

Цитата
Сообщение от talis
Посмотреть сообщение

Не по теме:

Chelioss, это не указатель. Массив чистой воды

Не правильно. name — это указатель на массив, причем name — это константный указатель.



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:41

 [ТС]

8

Да, кстати, не заметил, это символьный массив.



0



186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:42

9

Цитата
Сообщение от BoBaH26
Посмотреть сообщение

Chelioss, так а как тогда? Через copy, как сказал talis?

Да, либо самому вручную каждый элемент присвоить.



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:43

 [ТС]

10

Цитата
Сообщение от Chelioss
Посмотреть сообщение

Да, либо самому вручную каждый элемент присвоить.

Ну это не есть хорошо, т.к. у меня массив из структур, а мне его надо отсортировать, и для каждого MasList[i].name писать вручную…. Можно с ума сойти..



0



794 / 546 / 61

Регистрация: 11.05.2010

Сообщений: 1,298

Записей в блоге: 1

20.09.2011, 23:44

11

Chelioss, где он объявлен как указатель?

min — это объект типа List. В struct List есть объявление char name [30];. Соответственно, min.name — массив char из 30 элементов.

Добавлено через 24 секунды

Цитата
Сообщение от Chelioss
Посмотреть сообщение

Да, либо самому вручную каждый элемент присвоить.

Не имеет смысла. Есть библиотечные функции для копирования строк и памяти.



0



Chelioss

186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:46

12

Цитата
Сообщение от BoBaH26
Посмотреть сообщение

Ну это не есть хорошо, т.к. у меня массив из структур, а мне его надо отсортировать, и для каждого MasList[i].name писать вручную…. Можно с ума сойти..

Можно самому написать функцию подобной strcpy. Ну или используйте strcpy.

Добавлено через 1 минуту

Цитата
Сообщение от talis
Посмотреть сообщение

Chelioss, где он объявлен как указатель?
min — это объект типа List. В struct List есть объявление char name [30];. Соответственно, min.name — массив char из 30 элементов.

C++
1
2
char *ptr = name; // работает. Почему? Потому, что name - это char *.
strcpy(name1,name2); // Смотрим на прототип функции char * strcpy ( char * destination, const char * source );

Конечно, надо по другому объяснять, а не примеры приводить, но я просто знаю без доказательства)



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:48

 [ТС]

13

Не совсем понял с пунктом 1



0



794 / 546 / 61

Регистрация: 11.05.2010

Сообщений: 1,298

Записей в блоге: 1

20.09.2011, 23:50

14

Цитата
Сообщение от Chelioss
Посмотреть сообщение

char *ptr = name; // работает. Почему? Потому, что name — это char *.

Работает благодаря приведению типов. Объявление смотрите — char name[30].



0



Chelioss

186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:50

15

Цитата
Сообщение от BoBaH26
Посмотреть сообщение

Не совсем понял с пунктом 1

Вы про

C++
1
char *ptr = name;

?
name имеет тип const char *, поэтому его можно присвоить другому указателю.



0



talis

794 / 546 / 61

Регистрация: 11.05.2010

Сообщений: 1,298

Записей в блоге: 1

20.09.2011, 23:52

16

C++
1
char name [30];

Какой тип объявлен?



0



186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:52

17

Цитата
Сообщение от talis
Посмотреть сообщение

Работает благодаря приведению типов. Объявление смотрите — char name[30].

А что такое name? без []? Он по вашему мнению вообще не существует без []. А со [] — это всего лишь i-тый символ, а не массив.



0



30 / 30 / 5

Регистрация: 02.12.2010

Сообщений: 255

20.09.2011, 23:54

 [ТС]

18

char *ptr = name;
Получается, мы символьному указателю ptr присваиваем адрес первого элемента массива?



0



794 / 546 / 61

Регистрация: 11.05.2010

Сообщений: 1,298

Записей в блоге: 1

20.09.2011, 23:55

19

Chelioss, по моему мнению (и позвольте мне самому его высказывать), name без [] — это массив из 30-ти char, как и объявлено выше. А к указателю оно приводится автоматически благодаря приведению типов.

Добавлено через 24 секунды

Цитата
Сообщение от BoBaH26
Посмотреть сообщение

char *ptr = name;
Получается, мы символьному указателю ptr присваиваем адрес первого элемента массива?

Да. Адрес первого элемента массива name.



0



186 / 186 / 21

Регистрация: 08.01.2011

Сообщений: 1,139

20.09.2011, 23:59

20

talis
Так мы ни к чему и не придем. Нужно какое-то доказательство.



0



Okay, so, ignoring my lazy coding (this is just to get the program to work, I’ll clean it up after I get it working). I’ve set up a couple of if statements that will throw exceptions if I don’t get the input I’d like.

#include<string>
#include<iostream>
using namespace std;

int main()
{

    bool flag = false;
    int month, day, year;
    void header();

    class monthClassException
    {
    public:
        monthClassException()
        {
            message = "Invalid Month"; 
        }
        monthClassException(string str)
        {
            message = str;
        }
        string what()
        {
            return message;
        }

    private:
        string message;
    };
    class dayClassException
    {
    };
    class yearClassException
    {
    };


    header();

    do 
    {
        try
        {
            cout << "Please enter your date of birth (MM-DD-YYYY): " << endl;
            cin >> month;

            cin.ignore(10,'-');
            cin >> day;

            cin.ignore(10,'-');
            cin >> year;


            if (month > 12 || month < 1)
                throw monthClassException("Invalid Month Entry");

            if( ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) || day < 1)
                throw dayClassException();

            else if ( ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && day > 31) || day < 1)
                throw dayClassException();

            else if (month == 2 && year % 4 != 0 && day > 28)
                throw dayClassException();

            else if((month == 2 && year % 4 = 0) && day > 29)
                throw dayClassException();
        }
        catch(monthClassException mCEO)
        {
            cout << mCEO.what() << endl;
            system("pause");
        }
        catch(dayClassException)
        {
            cout << "Invalid Day Entered for Selected Month" << endl;
            system("pause");
        }
        catch(yearClassException yCEO)
        {
        }
    }while(!flag);


    return 0;
}

I’m getting my error at that very last exception:

            else if((month == 2 && year % 4 = 0) && day > 29)
                throw dayClassException();

it’s saying that month is an invalid l-value (Why now? At the very end after I’ve already used it -catastrophically, I will admit.) It could be something really obvious that I fail to see because I’m the one who coded it, or it could be because my really really crazy if statements messed something up somewhere.

Any ideas?

asked Mar 23, 2014 at 18:23

WTFNo's user avatar

1

Here is the error:

   year % 4 = 0

you probably meant to write ==

answered Mar 23, 2014 at 18:24

thumbmunkeys's user avatar

thumbmunkeysthumbmunkeys

20.6k8 gold badges63 silver badges110 bronze badges

1

= operator as in

year % 4 = 0

means assignment, not comparison. Hence your error.
Fix it to

year % 4 == 0

answered Mar 23, 2014 at 18:26

Mauren's user avatar

MaurenMauren

1,9552 gold badges18 silver badges28 bronze badges

You have year % 4 = 0.
I think you have a typo: you may want year % 4 == 0.

In addition, I prefer using parentheses to make the code clearer:

...
else if ((month == 2) && (year % 4 == 0) && (day > 29)) {
    throw dayClassException();
}

answered Mar 23, 2014 at 18:27

Mr.C64's user avatar

Mr.C64Mr.C64

41.7k14 gold badges86 silver badges162 bronze badges

You have a the assignment operator = in your condition instead of the comparison operator ==.

That’s pretty clearly a logic error. However, why is it a compiler error? After all, C++ allows assignment inside a condition, and that is something you might legitimately do.

In your case, month == 2 && year % 4 = 0 is processed as ((month == 2) && (year % 4)) = 0 (see C++ Operator Precedence). That expression in the parens evaluates to a temporary. But the left side of an assignment operator must refer to a storage address you can write to (an l-value). So your code is invalid for the same reason that 3 = 3 is invalid. Visual Studio calls this error C2106.

Community's user avatar

answered Mar 23, 2014 at 18:57

Alex P's user avatar

Alex PAlex P

1,55911 silver badges23 bronze badges

A suggestion in this regard, is to always put the constant on the left hand side of a comparison statement. It helps prevent logical errors. As an example consider the code

    if year == 0 

and mistakenly you had written:

    if year = 0 

the result would have been a logical error.
Instead putting the constant 0 on the left side, such that

     if 0 = year

would generate a syntax error at compilation, hence preventing you from committing a logical error (that can be harder to debug)

answered Mar 23, 2014 at 18:37

Hashim Sharif's user avatar

Хорошо, так что, игнорируя мое ленивое кодирование (это просто для того, чтобы заставить программу работать, я уберу ее после того, как она заработает). Я настроил пару операторов if, которые будут генерировать исключения, если я не получу желаемый ввод.

#include<string>
#include<iostream>
using namespace std;

int main()
{

bool flag = false;
int month, day, year;
void header();

class monthClassException
{
public:
monthClassException()
{
message = "Invalid Month";
}
monthClassException(string str)
{
message = str;
}
string what()
{
return message;
}

private:
string message;
};
class dayClassException
{
};
class yearClassException
{
};header();

do
{
try
{
cout << "Please enter your date of birth (MM-DD-YYYY): " << endl;
cin >> month;

cin.ignore(10,'-');
cin >> day;

cin.ignore(10,'-');
cin >> year;if (month > 12 || month < 1)
throw monthClassException("Invalid Month Entry");

if( ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) || day < 1)
throw dayClassException();

else if ( ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && day > 31) || day < 1)
throw dayClassException();

else if (month == 2 && year % 4 != 0 && day > 28)
throw dayClassException();

else if((month == 2 && year % 4 = 0) && day > 29)
throw dayClassException();
}
catch(monthClassException mCEO)
{
cout << mCEO.what() << endl;
system("pause");
}
catch(dayClassException)
{
cout << "Invalid Day Entered for Selected Month" << endl;
system("pause");
}
catch(yearClassException yCEO)
{
}
}while(!flag);return 0;
}

Я получаю свою ошибку в этом последнем исключении:

            else if((month == 2 && year % 4 = 0) && day > 29)
throw dayClassException();

он говорит, что месяц — недопустимое l-значение (почему сейчас? В самом конце, после того, как я его уже использовал — катастрофически, я признаю.) Это может быть чем-то действительно очевидным, что я не вижу, потому что я один кто это закодировал, или это может быть потому, что я действительно сумасшедший, если заявления где-то напутали.

Есть идеи?

-3

Решение

Вот ошибка:

   year % 4 = 0

ты наверное хотел написать ==

4

Другие решения

= оператор как в

year % 4 = 0

означает назначение, а не сравнение. Отсюда твоя ошибка.
Исправить это

year % 4 == 0

0

У тебя есть year % 4 = 0,
Я думаю, что у вас есть опечатка: вы можете хотеть year % 4 == 0,

Кроме того, я предпочитаю использовать скобки, чтобы сделать код более понятным:

...
else if ((month == 2) && (year % 4 == 0) && (day > 29)) {
throw dayClassException();
}

0

У вас есть оператор присваивания = в вашем состоянии вместо оператора сравнения ==,

Это довольно ясно логическая ошибка. Тем не менее, почему это компилятор ошибка? В конце концов, C ++ позволяет присваивать внутри условия, и это то, что вы могли бы законно делать.

В твоем случае, month == 2 && year % 4 = 0 обрабатывается как ((month == 2) && (year % 4)) = 0 (увидеть Приоритет оператора C ++). Это выражение в скобках оценивается как временное. Но левая часть оператора присваивания должна ссылаться на адрес памяти, на который вы можете записать ( л-значение). Таким образом, ваш код недействителен по той же причине, что 3 = 3 является недействительным. Visual Studio вызывает эту ошибку C2106.

0

В связи с этим предлагается всегда указывать константу в левой части оператора сравнения. Это помогает предотвратить логические ошибки. В качестве примера рассмотрим код

    if year == 0

и по ошибке вы написали:

    if year = 0

результат был бы логической ошибкой.
Вместо этого поместите постоянную 0 на левой стороне, так что

     if 0 = year

будет генерировать синтаксическую ошибку при компиляции, что не позволит вам совершить логическую ошибку (что может быть сложнее отладить)

0

Member Avatar for firebird102085


I am just starting to teach myself C++ and i have no coding experience so please bear with me on this if I ask you to explain your reasoning behind your response.

My code is:

// operating with varables
#include <iostream>
using namespace std;

//declarations
char STAR;
int PRIME = 71;

//begin main body
int main ()
{
    int count, sum, ex, num;
    sum = count + PRIME; 
    num = count * 1 + 2;
    (sum + count = ex);
    ex = sum * count;
    count = 25.67;
    cout << " Count = " << count << ", Sum = " << sum << ", Prime = " << PRIME << endl;
    return 0;

}

Debug errors received:

Error   1   error C2106: '=' : left operand must be l-value (error on line in bold)
Warning 2   warning C4244: '=' : conversion from 'double' to 'int', possible loss of data

Let me know what you all think.

Edited

by Dani because:

Formatting fixed


Recommended Answers

How about:

ex=(sum+count);

?

Also the value 25.67 has a fractional part and an integer does not.
If you want the value to keep the .67, you will need to make the count a double (or other type of floating point number).

The warning you …

Jump to Post

All 4 Replies

Member Avatar for thines01


thines01

401



Postaholic



Team Colleague



Featured Poster



How about:

ex=(sum+count);

?

Also the value 25.67 has a fractional part and an integer does not.
If you want the value to keep the .67, you will need to make the count a double (or other type of floating point number).

The warning you got means the framework will convert that double to an integer and it will lose the fractional part.

Edited

by thines01 because:

clarity

Member Avatar for subith86


Error 1 error C2106: ‘=’ : left operand must be l-value (error on line in bold)

Did you mean to put the value you get after summing sum and count into ex. If so, you should do like this.

ex = sum + count;

Warning 2 warning C4244: ‘=’ : conversion from ‘double’ to ‘int’, possible loss of data

count is declared as an int, which means it can hold values like 100, 101, 102… but not 101.43 or 3.14. But here you are trying to assign 25.67 to count. This is not an error, but eventually your count will ignore 0.67 and store only 25. So, if the 0.67 is important in your case you should use data types like double or float for count

Member Avatar for MandrewP


MandrewP

60



Junior Poster in Training



I am just starting to teach myself C++ and i have no coding experience so please bear with me on this if I ask you to explain your reasoning behind your response.

My code is:

>     // operating with varables
>     #include <iostream>
>     using namespace std;
>     
>     //declarations
>     char STAR;
>     int PRIME = 71;
>     
>     //begin main body
>     int main ()
>     {
>       int count, sum, ex, num;
>       sum = count + PRIME; 
>       num = count * 1 + 2;
>       (sum + count = ex);
>       ex = sum * count;
>       count = 25.67;
>       cout << " Count = " << count << ", Sum = " << sum << ", Prime = " << PRIME << endl;
>       return 0;
>     
>     }
Debug errors received:
Error 1   error C2106: '=' : left operand must be l-value (error on line in bold)
Warning   2   warning C4244: '=' : conversion from 'double' to 'int', possible loss of data

Let me know what you all think.

Keep in mind that the «=» symbol is an assignment operator — NOT an equals sign. For example, if you write: x = 10; do not get into the habit of saying x equals 10! That is not what’s happening. In C++, this is a valid statement: x = x + 1; but mathematically that would be incorrect, since x cannot be equal to itself PLUS one more. Always say, «x is assigned the value of 10», or «x gets 10». It will mess you up later if you always think of the «=» sign as an equals sign — it’s not, it is an assignment operator.

Any variable, such as count or ex or sum, is a name for a memory location. If we say, «x = 10;» then we are saying «Place the value of 10 into the memory location that we call x». So any variable is a container of sorts that can hold something, and obviously that is what is required on the left hand side of an assignment operator, right? An l-value is just that, a container of sorts (memory location) that can hold a value, and that must be what is placed on the left side of an assignment operator.

Imagine that you had 3 bank accounts, and they were named sum, count and ex. And you had $50 in each account. Now, if you said to the bank teller: sum + count = ex then in essence you would be saying to transfer the $50 in your ex account and place it into your sum + count account. ??? That doesn’t make sense — left operand must be an l-value! But, if you said ex = sum + count then you would be saying «Take the $50 from my sum account and the $50 from my count account and place both in my ex account. Now that makes sense, since ex is a proper l-value, ie., one that can hold a value. Sum + count cannot hold a value, it is not a memory location, but rather is just a temporary value that is used in the middle of a calculation, and is just transient in nature. (Sum + count) is an r-value, one that goes on the right side of an assignment operator. R-values are not containers of any sort, like a memory location, but rather are just temporary values that come up in the middle of a calculation, which are soon discarded. So r-values generally go into l-values, but you had them reversed.

Just a note for clarification: ex = sum + count — here (sum + count) replaces the value in ex, it isn’t added to the existing contents of ex.

Edited

by ~s.o.s~ because:

Fixed formatting

Member Avatar for MandrewP


MandrewP

60



Junior Poster in Training




Reply to this topic

Be a part of the DaniWeb community

We’re a friendly, industry-focused community of developers, IT pros, digital marketers,
and technology enthusiasts meeting, networking, learning, and sharing knowledge.

Понравилась статья? Поделить с друзьями:
  • Ошибка c1718 тойота
  • Ошибка c2104 mitsubishi asx
  • Ошибка c1761 toyota prado 150
  • Ошибка c1713 toyota
  • Ошибка c1751 тойота прадо 120