Dado um vetor de números complexos, quero obter seus valores absolutos:
std::vector<std::complex<double>> in; // filling omitted
std::vector<double> out(in.size());
std::transform(in.begin(), in.end(), out.begin(),
&std::abs<std::complex<double>> // (1)
// [](std::complex<double> z){ return std::abs(z); } // (2)
);
No meu entendimento, as linhas (1) e (2) deveriam ter o mesmo efeito.
No entanto, enquanto a linha (2) é compilada corretamente, a linha (1) produz um erro:
../../../include/c++/12/bits/stl_algo.h:4263:31: error: cannot convert 'std::complex<double>' to 'double' in assignment
4263 | *__result = __unary_op(*__first);
| ~~~~~~~~~~^~~~~~~~~~
| |
| std::complex<double>
Por que recebo esse erro? Por que a função anônima é necessária aqui?
O argumento do modelo
std::abs<T>(std::complex<T>)
é o tipoT
usado para representar o arquivostd::complex<T>
. Você está instanciandostd::abs<std::complex<double>>
o que retorna umstd::complex<double>
mas você querstd::abs<double>(const std::complex&)
.Para obter detalhes, indico https://en.cppreference.com/w/cpp/numeric/complex/abs e https://en.cppreference.com/w/cpp/numeric/complex .
Escolher o ponteiro de funções via
std::abs<double>
não funcionará porquestd::abs
está sobrecarregado e obter seu endereço exigiria escolher a sobrecarga correta por meio de astatic_cast
. Além disso, as funções padrão não podem receber seu endereço, a menos que sejam funções explicitamente endereçáveis. Usar o lambda é claramente a alternativa mais simples.