如何为涉及对象成员、间接寻址和强制转换的排序算法实现lambda函数
How to implement a lambda function for a sort algorithm involving object members, indirection, and casting?
我正在编写一些代码,其中有一部分是一次性排序函数。为了实现它,我决定最简单的方法是重载运算符<作用我更愿意做的是通过使用某种boost::bind、boost::phoenix、lambda或其他类型的实现,使排序的实现更接近实际调用。不幸的是,我无法访问新的C++11功能。下面是一些示例代码。
// In a header
struct foo
{
char * a;
char * c_str() { return a; }
}
// In a header
struct bar
{
foo * X;
bar(foo * _X) : X(_X) {}
bool operator < (const bar& rhs) const
{
return std::string(X->c_str()) < std::string(rhs.X->c_str());
}
};
struct bars : public std::vector<bar> { ... some stuff };
// Some other header
bars Bs;
// A cpp file
... other stuff happens that fills the Xs vector with objects
...::Function()
{
// Current use and it works fine
std::sort(Bs.begin(), Bs.end())
// Would like something that accomplishes this:
// std::sort(Bs.begin(), Bs.end(),
// std::string(lhs.X->c_str()) < std::string(rhs.X->c_str()))
// A non-working example of what I'm trying to do
// std::sort(Xs.begin(), Xs.end(),
// std::string((bind(bar::X->c_str(), _1)) <
// std::string((bind(bar::X->c_str(), _2)) )
}
当我试图弄清楚如何访问成员指针、成员函数,然后在boost::bind函数中强制转换结果时,我迷失了方向。
谢谢你的帮助。
我相信,使用的大量帮助,您可以扭转局面
- 提升Phoenix
bind
和lambda
- 提升绑定
protect
然而,我已经学会了避免这些情况编辑事实上,下面就是这样一个装置。我发现这很容易出错,很难推理。
从本质上讲,你所看到的是对德米特定律的违反。如果您"只是"编写代码(不是在lambda中),那么它已经处理了太多任务。
所以我要做的第一件事就是重新思考课堂设计。
我要做的第二件事是从你的比较者那里提取/不同的责任。注意,比较器做三件事:
- 访问lhs中X的c_str()
- 访问rhs中X的c_str()
- 比较两者
前两个步骤显然是提取的候选步骤。让我们先写一个通用比较器:
template <typename F>
struct compare_by_impl {
compare_by_impl(F f = F{}) : _f(std::move(f)) {}
template <typename T, typename U>
bool operator()(T const& a, U const& b) const {
return _f(a) < _f(b);
}
private:
F _f;
};
和往常一样,有一个可以推导访问器类型的工厂函数是很好的(如果你可以在那里使用Phoenix,它将省去你指定表达式模板中涉及的(神秘的)类型名的麻烦):
template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor&& f) {
return compare_by_impl<Accessor>(std::forward<Accessor>(f));
}
现在,您已经可以使用排序调用来移动实现:
void Function()
{
struct accessX_c_str {
std::string operator()(bar const& b) const {
return b.X->c_str();
}
};
std::sort(Bs.begin(), Bs.end(), comparer_by(accessX_c_str()));
}
我个人会把它留在那里。
这里有一些更扭曲的装置:
// to avoid `comparer_by`
std::sort(Bs.begin(), Bs.end(), phx::bind(accessX_c_str(), arg1) < phx::bind(accessX_c_str(), arg2));
// to avoid any helper types (!?!?!? untested!)
std::sort(Bs.begin(), Bs.end(),
phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg1)))
< phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg2)))
);
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将分数转换为十进制数并对其进行排序
- C/C++ - 将浮点数转换为字节数组,以便字节保持排序
- 如何有效地对__m256i向量的字节进行重新排序(将int32_t转换为uint8_t)?
- 如何为涉及对象成员、间接寻址和强制转换的排序算法实现lambda函数
- C++中的合并排序:无法在合并函数中传递数组 - 转换为'int*'无效
- 使用最小运算将给定字符串转换为排序字符串
- 在C++中对数字数组进行排序时,是否必须将字符串转换为双精度
- 将 BST 转换为排序的双向链表
- 将范围有限的浮点数转换为无符号的整数,以保持排序顺序和精度
- 尝试将伪代码转换为合并排序的实际代码
- 将有符号整数值转换为可排序的无符号C++的标准兼容方法是什么?
- 用qsort -正确的类型转换排序2D数组
- 用于排序容器的隐式转换为显式bool类型
- 将字符串转换为数字并排序的数组
- 对已转换为字符串的int向量进行排序