gpt4 book ai didi

c++ - C++03 中带有 std::bind2nd 的复合函数

转载 作者:行者123 更新时间:2023-11-30 05:43:54 24 4
gpt4 key购买 nike

我想让一些函数/仿函数充当复合函数/仿函数:

具体来说,我有函数 f(x, y) , 和 g(u, v) ,我想创建一个函数指针或仿函数 h(t) = f(g(t,C1), C2) ,这样我就可以传递仿函数 h进入 for_each() 循环,其中 C1、C2 是一些常量。

或者,让我们在我的真实示例中这样做:我有一个函数 double g(T1 u, T2 v)计算一些东西。我想遍历所有 u来自 vector vector<T1> vecInput , 带有固定的第二个参数 t2VConst .计算完所有这些数字后,我想将它们保存到一个 vector 中 vector<double> results .

我想用类似这样的东西来做:

foreach(vecInput.begin(), vecInput.end(), std::bind2nd(&results::push_back, std::bind2nd(g, t2VConst)))

请注意,在本例中,f(x,y)函数真的是一个成员函数vector::push_back . (看来push_back只有一个参数,但是作为成员函数,它多了一个参数,就是对象本身。)

更糟的是,我真的必须用 C++03 来做,而不是 C++11。有什么解决办法吗?此外,我希望解决方案可以更简洁(如果可以像上面那样在一行中完成)。

更新

bind2nd() 的相关问题:我遇到了编译错误,现在我将其简化为更简单的代码来查看它:

#include <functional>
#include <algorithm>

#define CASE2 // choose define of CASE1 to CASE3

#ifdef CASE1
double g(double x, double y) // 1. OK
#endif
#ifdef CASE2
double g(double &x, double y) // 2. overload error
#endif
#ifdef CASE3
double g(double *x, double y) // 3. OK
#endif
{
#ifdef CASE2
x = 5.0;
#endif
#ifdef CASE3
*x = 5.0;
#endif
// Note: no case1, since in case 1, x is a local variable,
// no meaning to assign value to it.

return 3.0;
}

int main(int argc, char *argv[])
{
double t = 2.0;
double u;

#if defined(CASE1) || defined(CASE2)
u = std::bind2nd(std::ptr_fun(&g), 3.0)(t);
#endif
#ifdef CASE3
u = std::bind2nd(std::ptr_fun(&g), 3.0)(&t);
#endif
}

我不知道为什么 CASE 2 失败了...

最佳答案

I have functions f(x, y), and g(u, v), and I want to create a function pointer or functor h(t) = f(g(t,C1), C2). I have to do it in C++03.

不可能仅使用 C++03 标准库中可用的适配器来组合函数。显然,没有什么能阻止您自己实现此功能。但是,如果您想利用任何现有库并获得真正的单行代码,则几乎没有其他选择:

选项 #1:SGI 扩展

libstdc++ 附带 the standard library extensions from SGI .它提供了几个额外的适配器和仿函数,即: compose1 , compose2 constant1 .它们可以通过以下方式组合:

#include <functional>
#include <ext/functional>

int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;

__gnu_cxx::compose2(std::ptr_fun(&f)
, std::bind2nd(std::ptr_fun(&g), C1)
, __gnu_cxx::constant1<int>(C2)
)(arg);

选项 #2:TR1 扩展

C++11 的初始实现 std::bind也可以在 tr1 中找到扩展库:

#include <tr1/functional>

int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;

std::tr1::bind(&f
, std::tr1::bind(&g
, std::tr1::placeholders::_1
, C1)
, C2
)(arg);

选项 #3:Boost 库

Boost.Bind 库可能是最便携的解决方案:

#include <boost/bind.hpp>

int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;

boost::bind(&f, boost::bind(&g, _1, C1), C2)(arg);

The f(x,y) function is really a member function vector::push_back

在 C++03 中绑定(bind)成员函数时,您通常会使用 std::mem_fun 连同 std::bind1st 绑定(bind)对象参数:

Class object;
std::bind1st(std::mem_fun(&Class::func), &object)(arg);

但是,对于通过引用获取其参数的成员函数,这将失败。再一次,您可以改用 Boost/TR1:

boost::bind(&std::vector<double>::push_back
, &results
, boost::bind(&g, _1, C1)
)(arg);

请注意,当切换到 C++11 时,您需要手动解析重载的 std::vector<double>::push_back .

但幸运的是,您的用例有资格被 std::transform 替换算法与 std::back_inserter , 这将负责调用 push_back转换参数的 vector 成员函数。

#include <algorithm>
#include <functional>
#include <iterator>

int g(int u, int v);
const int C1 = 2;
std::vector<int> input, output;

std::transform(input.begin(), input.end()
, std::back_inserter(output)
, std::bind2nd(std::ptr_fun(&g), C1));

DEMO

关于c++ - C++03 中带有 std::bind2nd 的复合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30046499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com