Em C++ , todas as expressões são avaliadas. O resultado da avaliação é um valor e pode ser usado em quaisquer lugares.
Como você já sabe, expressões usando operadores aritméticos, relacionais e lógicos3 são avaliados. O valor resultante é um número. Para os operadores relacionais e lógicos, este número pode ser 0 (que significa falso) ou 1 (que significa verdadeiro). Por exemplo:
| 3 + 5 * 4 % (2 + 8) | tem valor 3; | |
| 3 < 5 | tem valor 1; | |
| x + 1 | tem valor igual ao valor da variável x mais um; | |
| (x < 1) || (x > 4) | tem valor 1 quando o valor da variável x é fora do intervalo [1,4], e 0 quando x está dentro do intervalo. | 
O formato do operador de atribuição é:
Um 
 (do inglês “left-hand-side value” - valor a esquerda) é um
valor que se refere a um  endereço na memória do computador.  Até agora,
o único  “lvalue” válido visto no curso  é o nome de  uma variável.  A
maneira  que a atribuição  funciona é  a seguinte:  a expressão  do lado
direito  é avaliada,  e o  valor é  copiado para  o endereço  da memória
associada ao “lvalue”.  O tipo  do objeto do “lvalue” determina como
o valor da 
 é armazenada na memória.
Expressões de atribuição, assim como expressões, têm valor. O valor de uma expressão de atribuição é dado pelo valor da expressão do lado direito do =. Por exemplo:
| x = 3 | tem valor 3; | |
| x = y+1 | tem o valor da expressão y+1. | 
Como consequência do fato que atribuições serem expressões que são associadas da direita para esquerda, podemos escrever sentenças como:
i = j = k = 0;
Que, usando parênteses, é equivalente a i = (j = (k = 0)). Ou seja, primeiro o valor 0 é atribuído a k, o valor de k = 0 (que é zero) é atribuído a j e o valor de j = (k = 0) (que também é zero) é atribuído a i.
Uma característica muito peculiar de C++ é que expressões de atribuição podem ser usados em qualquer lugar que um valor pode ser usado. Porém você deve saber que usá-lo dentro de outros comandos produz um efeito colateral que é alterar o valor da variável na memória. Portanto, a execução de:
    int quadrado, n = 2;
    cout << "Quadrado de " << n << " eh menor que 50? " << ((quadrado = n * n) < 50) << endl;
causa não apenas que o valor 4 seja impresso, como a avaliação da expressão relacional dentro do cout faz com que o número 4 seja copiado para o endereço de memória associado com a variável quadrado. Note que é necessário usar parênteses em quadrado = n * n já que = tem menor precedência que o operador relacional <.
Agora compare o exemplo anterior com o próximo, no qual o valor 4 é impresso, mas sem nenhum efeito colateral:
    int quadrado, n = 2;
    cout << "Quadrado de " << n << " eh menor que 50? " << (n * n < 50) << endl;
Note que agora não há necessidade de parênteses para a expressão n * n porque * tem maior precedência que o operador relacional <.
