Ответ 1
Да, вы можете быть уверены. Оптимизация вызова приведет к изменению наблюдаемого поведения вашей программы, и компилятору не разрешено это делать (за исключением случая с RVO).
Это известно как правило as-if.
У меня есть программа на С++, в которой я хочу вставить значения по умолчанию для любых ключей, отсутствующих в std::map
. Я думаю, что самый простой способ сделать это - использовать std::map::operator[]()
как команду касания POSIX, то есть оставить значение неизменным, если оно уже существует, но создать его, если это не так. Для ,
#include <map>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> keys = {0, 1};
map<int, int> m;
m[1] = 5;
m[2] = 12;
for (const int i : keys)
{
m[i]; // touch value
}
for (auto const & kv : m)
{
cout << kv.first << ", " << kv.second << endl;
}
}
Могу ли я быть уверенным, что компилятор не будет оптимизировать инструкции m[i];
, так как я не делаю с ними что-нибудь? (Явным образом не назначаю, а не читаю.)
Да, вы можете быть уверены. Оптимизация вызова приведет к изменению наблюдаемого поведения вашей программы, и компилятору не разрешено это делать (за исключением случая с RVO).
Это известно как правило as-if.
Да, вы можете быть уверены. Возможно, это более интуитивно понятно, если вы считаете, что соответствующая строка эквивалентна этому:
m.operator[](i);
& hellip; вы не ожидаете, что произвольные вызовы функций будут оптимизированы из вашей программы, если они что-нибудь сделают.
Оператор [] действительно устанавливает значение по умолчанию, которое было бы в этом ключевом местоположении, если вы его не присвоите.
Если k не соответствует ключу любого элемента в контейнере, функция вставляет новый элемент с этим ключом и возвращает ссылку к его отображаемому значению. Обратите внимание, что это всегда увеличивает контейнер размер на единицу, даже если для элемента не присвоено сопоставленное значение ( элемент создается с использованием его конструктора по умолчанию).