Если я выполню этот код:

vector<complex<double> >
idft( vector<complex<double> > * v)
{

    for_each(v->begin(), v->end(), conj);

То компилятор дает мне следующую ошибку:

dft.cpp: In function 'std::vector<std::complex<double>, std::allocator<std::complex<double> > > idft(std::vector<std::complex<double>, std::allocator<std::complex<double> > >*)':
dft.cpp:38: error: no matching function for call to 'for_each(__gnu_cxx::__normal_iterator<std::complex<double>*, std::vector<std::complex<double>, std::allocator<std::complex<double> > > >, __gnu_cxx::__normal_iterator<std::complex<double>*, std::vector<std::complex<double>, std::allocator<std::complex<double> > > >, <unresolved overloaded function type>)'

Если я применяю cons () только для одного элемента, он отлично работает:

vector<complex<double> >
idft( vector<complex<double> > * v)
{

    conj(v->at(0));

Как я могу применить конъюнктуру () для всего вектора без использования цикла?

3
user1209304 18 Фев 2016 в 14:03

4 ответа

Лучший ответ

for_each редко бывает хорошей идеей в современном (C ++ 11 и выше) C ++.

void idft( std::vector<std::complex<double> >& v)
{
  for (auto& x : v)
    x = std::conj(x);
}

Или даже:

template<class Range>
void idft( Range& v)
{
  for (auto& x : v)
    x = std::conj(x);
}

Чистый, общий, правильный и удобный для чтения.

4
Yakk - Adam Nevraumont 18 Фев 2016 в 15:04

Ответ, который был выбран (теперь он изменен) с помощью for_each, является совершенно неверным . Вы не можете использовать for_each, потому что он не изменяет объект, который вы повторяете. Вот как это сделать с помощью std::transform и простой лямбда-функции.

std::transform(v->begin(),v->end(), v->begin(), [](const std::complex<double>& c) -> std::complex<double> { return std::conj(c); });
4
The Quantum Physicist 25 Окт 2016 в 12:25

Используйте std :: transform, если ваша функция (конъюнктура) не изменяет свой входной аргумент.

0
Erik Alapää 18 Фев 2016 в 12:05

Поскольку std::conj содержит несколько перегрузок шаблонных функций, компилятор не Я знаю, какой из них следует выбрать, только по имени функции.

template< class T >
complex<T> conj( const complex<T>& z );       (1)     
template< class DoubleOrIngeter >
std::complex<double> conj( DoubleOrInteger z );       (3)     (since C++11)

Ты мог бы

typedef complex<double> (*CONJ_TYPE)( const complex<double>& z );
for_each(v->begin(), v->end(), static_cast<CONJ_TYPE>(conj<double>));

ПРЯМОЙ ЭФИР

0
songyuanyao 18 Фев 2016 в 11:33