У меня есть проблема с попыткой конвертировать фрагмент кода С++ 11 для повышения.
Предположим, что у меня есть простой класс:
class C
{
public:
typedef std::vector<std::string> Info;
public:
explicit C(Info const& info)
: info_(info)
{}
std::string text(Info::size_type i) const
{
return info_[i];
}
private:
Info info_;
};
Теперь, если у меня есть вектор классов C, я хотел бы получить максимальную ширину определенного элемента C :: Info, используя алгоритм std :: max_element.
С lambdas С++ 11 я мог бы сделать это следующим образом:
C::Info::size_type const Info_0 = 0;
C::Info::size_type const Info_1 = 1;
C::Info::size_type const Info_2 = 2;
int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
[info_n](C const& lhs, C const& rhs)
{ return lhs.text(info_n).length() < rhs.text(info_n).length(); });
return max != c_vec.end() ? max->text(info_n).length() : 0;
}
Но проблема в том, что я не могу использовать С++ 11, поэтому мне нужно идти с повышением.
На данный момент код, который я смог придумать, выглядит следующим образом:
int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
boost::lambda::bind(&C::text, boost::lambda::_1, boost::lambda::var(info_n)) <
boost::lambda::bind(&C::text, boost::lambda::_2, boost::lambda::var(info_n)));
return max != c_vec.end() ? max->text(info_n).length() : 0;
}
Хотя это явно не то, что я хочу. Сравнение выполняется над объектами std :: string, и я застреваю, пытаясь понять, как вызвать эту функцию length()...
Ваша помощь весьма приветствуется.
Не обязательно ответ, который вы запрашиваете, но для подхода non С++ 11 полезно знать, что лямбда-выражения похожи на структуры с помощью оператора функции.
Таким образом, ваш пример может быть реализован примерно так:
struct lambda_max
{
const C::Info::size_type& info_n;
lambda_max(const C::Info::size_type& info_n):info_n(info_n) {}
bool operator()(C const& lhs, C const& rhs) const
{
return lhs.text(info_n).length() < rhs.text(info_n).length();
}
};
int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
lambda_max(info_n));
return max != c_vec.end() ? max->text(info_n).length() : 0;
}
Здесь решение С++ 03, использующее Boost.Phoenix
#include <functional>
#include <boost/phoenix.hpp>
int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
namespace phx = boost::phoenix;
using namespace phx::arg_names;
std::vector<C>::const_iterator max = std::max_element(c_vec.begin(), c_vec.end(),
phx::bind(std::mem_fun_ref(&std::string::length), phx::bind(&C::text, arg1, phx::val(info_n))) <
phx::bind(std::mem_fun_ref(&std::string::length), phx::bind(&C::text, arg2, phx::val(info_n)))
);
return max != c_vec.end() ? max->text(info_n).length() : 0;
}
Я не слишком много тестировал, но, похоже, здесь работает.
get_max_width()
. Не огромная сделка, но больше раздражающего ограничения.