Em uma proposta padrão C++ , encontro um trecho de código estranho como o seguinte:
template <input_iterator I, sentinel_for<I> S, nothrow_forward_iterator I2>
constexpr auto uninitialized_copy(I first, S last, I2 d_first) -> I2 {
using T = iter_value_t<I2>;
I2 current = d_first;
try {
for (; first != last; ++first, (void)++current) {
::new (std::addressof(*current)) T(*first);
}
} catch (...) {
std::destroy(d_first, current);
throw;
}
}
Por que usar (void)++current
em vez de apenas ++current
aqui?
++first, (void)++current
usa o operador vírgula,
.Se
++first
for avaliado como um tipoT
e++current
para um tipoU
e houver umaoperator,
sobrecarga viável para argumentosT
/U
, então isso seria chamado deoperator,
sobrecarga.No entanto, não é pretendido que ele seja chamado. Ao fazer um dos dois operandos ter o tipo
void
, torna-se impossível que uma sobrecarga de,
seja escolhida e, em vez disso, ele sempre terá o significado embutido.É por isso que o código de biblioteca genérico deve sempre converter pelo menos um operando
void
ao usar o operador vírgula.