Использование std :: transform и tr1 :: bind для преобразования вектора из std :: complex - PullRequest
3 голосов
/ 19 апреля 2011

Учитывая std :: vector std :: complex, я хотел бы преобразовать его в вектор, содержащий только действительную часть комплекса, разделенную на некоторый постоянный коэффициент Прямо сейчас я делаю это:

std::vector<std::complex<double> > vec;
std::vector<double> realVec;
double norm = 2.0;
...
for (std::vector<std::complex<double> >::iterator it = vec.begin(), itEnd = vec.end(); it != itEnd; ++it)
    realVec.push_back((*it).real() / norm);

Конечно, это работает нормально, но я ищу способ использовать std :: transform для того же. Я попробовал:

transform(vec.begin(), vec.end(), back_inserter(realVec), tr1::bind(divides<double>(), tr1::bind(&complex<double>::real, tr1::placeholders::_1), norm));

Но это не сработает. У меня есть эта ошибка:

erreur: no matching function for call to ‘bind(<unresolved overloaded function type>, std::tr1::_Placeholder<1>&)’|

Я не понимаю, почему существует «неразрешенный тип перегруженной функции».

Может ли кто-нибудь объяснить мне, что не так?

Ответы [ 2 ]

4 голосов
/ 19 апреля 2011

К сожалению, вы не можете сделать это, по крайней мере, напрямую. Типы функций-членов Стандартной библиотеки (например, complex<double>::real) остаются неопределенными, поэтому реализация может предоставлять дополнительные перегрузки, а функции, которые там находятся, могут иметь дополнительные параметры с аргументами по умолчанию.

Фактически, нет переносимого способа получить адрес функции-члена стандартной библиотеки.

Лучше всего написать вспомогательную функцию:

template <typename T>
T get_real(const std::complex<T>& c) { return c.real(); }

и привязать к этому:

std::tr1::bind(&get_real<double>, std::tr1::placeholders::_1)
1 голос
/ 19 апреля 2011

std::complex<>::real() перегружен (см. C ++ 11 [сложный]).

template <typename T>
class complex {
    // ...
    T real() const; // getter
    void real( T ); // setter
    // ...
};

C ++ требует устранения неоднозначности, когда вы берете адрес перегруженной функции.В вашем случае вы должны сказать:

tr1::bind( static_cast<double(std::complex<double>::*)()const>( &std::complex<double>::real ),
           tr1::placeholders::_1 )

Да, это безобразно.

...