Что static_cast<T> делает с T&?

Так что я задал этот вопрос, и я возился с его решением через static_cast, (Между прочим, это решает проблему, я просто не уверен, понимаю ли я почему.)

В коде:

vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), static_cast<int>(foo.front()), 13);

Это static_cast просто построить R-значение int? Какая разница между этим и просто вызовом:

replace(begin(foo), end(foo), int{foo.front()}, 13);

РЕДАКТИРОВАТЬ:

Как следует из ответов static_cast действительно строит R-значение int: http://ideone.com/dVPIhD

Но этот код не работает в Visual Studio 2015. Это ошибка компилятора? Проверьте здесь: http://webcompiler.cloudapp.net/

2 ответа

Решение
  1. Да, это так же, как int{...}если .front() возвратил тип, который требовал сужающего преобразования. В таком случае, int(...) будет идентичным

  2. В случае ошибки программиста статическое приведение с меньшей вероятностью может сделать что-то опасное, например, преобразовать указатель в int, чем int(...),

Обратите внимание, что устранение приведений приводит к неопределенному поведению, так как передний элемент изменяется операцией замены, и это может привести к поломке std::replace,

я хотел бы использовать

template<class T>
std::decay_t<T> copy_of(T&& t){return std::forward<T>(t); }

Я здесь.

Что касается того, почему это не работает в MSVC...

MSVC помогает в ситуациях, когда вы приводите переменную типа T к T и продолжает ничего не делать. Это нарушает ваш код.

Существует флаг компилятора (/Zc:rvalueCast), который можно использовать, чтобы MSVC больше не нарушал ваш код.

Функция-член front возвращает ссылку на первый элемент непустого вектора.

С другой стороны стандартный алгоритм replace объявлен как

template <class ForwardIterator, class T>
  void replace (ForwardIterator first, ForwardIterator last,
                const T& old_value, const T& new_value)

принимает третий параметр также по ссылке. Таким образом, в общем случае первый элемент вектора может быть изменен алгоритмом, и в результате обработка других элементов вектора алгоритмом может быть некорректной.

Используя static_cast, временный объект создается и не будет изменяться алгоритмом, поэтому обработка всех элементов вектора будет корректной.

Что касается меня, то я предложил C++ предложение использовать ключевое слово auto в таких случаях. Например

replace(begin(foo), end(foo), auto( foo.front() ), 13);
Другие вопросы по тегам