Ответ 1
Ваш код, безусловно, должен быть хорошо сформирован. Я считаю, что GCC выполняет пересмотренную форму memoization; назад в С++ 11, объекты не могли быть изменены в постоянных выражениях, следовательно, было отлично, что бы кешировать результаты функции. На самом деле, совершенно очевидно из нескольких отчетов об ошибках Clang, которые GCC сделал именно так, см., Например, здесь:
Clang constexpr не выполняет кэширование. В С++ 14, даже не ясно, будет ли кеширование возможным, так что это похоже на пустая трата времени, чтобы инвестировать в нее сейчас.
Очевидно, им пришлось ввести некоторый дополнительный анализ в С++ 14, и они допустили ошибку: они предположили, что любой подобъект объекта constexpr
не может быть изменен в течение его жизненного цикла. Это явно не сохраняется в период строительства объекта-объекта. Если мы используем временную, а не x
, компилируем код. Если мы поместим все это в функцию constexpr
и удалим s constexpr
specifier, он работает.
Как ни странно, результаты rr
и vv
также кэшируются, но возвращается одна и та же ссылка, и вызов по значению полностью избегает этой проблемы:)
Отмечено как 79520.