Ряд компиляторов неправильно трактуют значения интегрального типа как значения r и создают незаконные временные при привязке к значению ссылки на const в некоторых выражениях. Это может привести к созданию необязательной ссылки на значение, которая фактически связана с неожиданным временным, а не с предполагаемым объектом. Чтобы предотвратить трудно найти ошибки времени выполнения, эта библиотека выполняет проверку времени компиляции, чтобы предотвратить выражения, которые в противном случае связывали бы необязательную ссылку на неожиданное временное. Как следствие, на некоторых компиляторах определенные функциональные возможности в дополнительных ссылках отсутствуют. Для того, чтобы поддерживать переносимость вашего кода в разных компиляторах, рекомендуется придерживаться минимального переносного интерфейса дополнительных ссылок: предпочтите прямую инициализацию и присвоение копий дополнительных ссылок на инициализацию копий и присвоение из<T&
>:
const int i = 0;
optional<const int&> or1;
optional<const int&> or2 = i;
or1 = i;
optional<const int&> or3(i);
or1 = optional<const int&>(i);
Компиляторы, которые, как известно, имеют эти недостатки, включают версии GCC 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; версии MSVC 8.0, 9.0, 10.0, 11.0, 12.0. Чтобы проверить, правильно ли компилятор реализует эталонную привязку, используйте эту тестовую программу.
#include <cassert>
const int global_i = 0;
struct TestingReferenceBinding
{
TestingReferenceBinding(const int& ii)
{
assert(&ii == &global_i);
}
void operator=(const int& ii)
{
assert(&ii == &global_i);
}
void operator=(int&&)
{
assert(false);
}
};
int main()
{
const int& iref = global_i;
assert(&iref == &global_i);
TestingReferenceBinding ttt = global_i;
ttt = global_i;
TestingReferenceBinding ttt2 = iref;
ttt2 = iref;
}