C++BUILDER 2009 中的 STL 库的 std::bind2nd的问题

morphia 2008-12-22 11:45:27
一个简单的C++使用STL的算法问题:
我有一个函数子 ObjectEqualID, 带入两参数, 结合 std::remove_if使用,需要使用std::bind2nd来绑定第二个参数,于是有以下的代码:



#include <functional>
#include <algorithm>

struct ObjectEqualID : public std::binary_function<Object, DWORD, bool>
{
bool operator ()(Object const& obj, DWORD dwObjID) const
{
return obj.GetObjID() == dwObjID;
}
};

Object_Iter p = std::remove_if(objs.begin(), objs.end(), std::bind2nd(ObjectEqualID(), dwObjID));



但是这段代码remove_if那一行怎么样都没有办法编译通过, 出现链接错误:
[TASM32 Error] AutoThread.asm(7735): Undefined symbol: @@std@%remove_copy_if$55std@%_Vector_iterator$6Object23std@%allocator$6Object%%t131std@%binder2nd$13ObjectEqualID%%$q55std@%_Vector_iterator$6Object23std@%allocator$6Object%%t1t131std@%binder2nd$13ObjectEqualID%$55std@%_Vector_itera1elpYZsgy

头文件已经正确加入, 后来经排除法(我换上了一个参数的函数子)后,发现是std::bind2nd有问题,于是自己操刀写了一个bind2nd, 链接正确通过, 并且成功, 百思不得其解, 今天整理代码,想把自己写的bind2nd整理至std2这个命名空间中, 居然发现同样的问题又出现了. 这回让我很头大, 因为这表明这个问题是和编译器有问题, 而不是因为STL中文件缺失或其它非编译器问题. 把bind2nd的命名空间去掉, 编译链接一切又正常.

为了让各位确定不是自己写的bind2nd的问题, 现把bind2nd的代码奉上:



template <typename _Pr_>
class binder2nd : public std::unary_function<typename _Pr_::first_argument_type,
typename _Pr_::result_type>
{
public:
binder2nd(_Pr_ pr, _Pr_::second_argument_type value2nd)
: m_pr(pr)
, m_value2nd(value2nd)
{

}

_Pr_::result_type operator ()(_Pr_::first_argument_type value) const
{
return m_pr(value, m_value2nd);
}

private:
_Pr_ m_pr;
_Pr_::second_argument_type m_value2nd;
};

template <typename _Pr_>
binder2nd<_Pr_> bind2nd(_Pr_ pr, typename _Pr_::second_argument_type value)
{
return binder2nd<_Pr_>(pr, value);
}



我现在预想最好的结果是, BCB应该在链接选项中有相应的兼容性选择项, 但是无耐我本人不才, 找不到.
还有劳各位大大排忧解难.

非常感谢
...全文
342 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
morphia 2008-12-23
  • 打赏
  • 举报
回复
谢谢楼上各位, 因为我以前一直用VC++, 所以还不是很习惯BCB的C++编译器, 看了楼上各位的回复后突然想到是不是因为我把所有的函数都放到头文件中的缘故, 因为我的那个包含有remove_if的函数是个static的, 然后我将其移动至.cpp文件中后, 编译通过了..!

to: jxw1987628
谢谢你提出我的bind2nd的问题, 我翻了一下stl的源代码, 的确和你说的是一样, 虽然我那样写不会导致有太多的问题, 不过还是非常感谢你, 在以后C++编程中我会注意的.

结贴啦.
jxw1987628 2008-12-23
  • 打赏
  • 举报
回复
/*
我在BCB 6.0中测试你上面的调用是可行的(可正常通过编译连接),就是你那个调用STL库的bind2nd

是可行的,不知道你后面是不是自己写了1个binder2nd类模板的代码,我看了下,对于你自己写的binder2nd

类模板的代码中的bind2nd 函数模板的实现部分是有问题的。

我将其该为如下也是可以通过编译连接。


*/

namespace MySpace
{
template <typename _Pr_>
class binder2nd : public std::unary_function<typename _Pr_::first_argument_type,
typename _Pr_::result_type>
{
public:
binder2nd(_Pr_ pr, _Pr_::second_argument_type value2nd)
: m_pr(pr)
, m_value2nd(value2nd)
{

}

_Pr_::result_type operator ()(_Pr_::first_argument_type value) const
{
return m_pr(value, m_value2nd);
}

private:
_Pr_ m_pr;
_Pr_::second_argument_type m_value2nd;
};

/* 这个是我修改后的
template <typename _Pr_,typename _Tp>
inline binder2nd<_Pr_>
bind2nd(const _Pr_& pr, const _Tp& __x)
{
typedef typename _Pr_::second_argument_type _Arg2_type ;
return binder2nd<_Pr_>(pr, _Arg2_type(__x));
}
*/

//这个是你原来自己的
template <typename _Pr_>
binder2nd<_Pr_> bind2nd(_Pr_ pr, typename _Pr_::second_argument_type value)
{
return binder2nd<_Pr_>(pr, value);
}

}

std::remove_if(objs.begin(), objs.end(),MySpace::bind2nd(ObjectEqualID(), dwObjID));
我来看看CB 2008-12-23
  • 打赏
  • 举报
回复
还是兼容性问题。
痞子酷 2008-12-23
  • 打赏
  • 举报
回复
Unix下测试没有问题:
template <class Operation>
class binder1st : public unary_function<typename
Operation::second_argument_type,
typename Operation::result_type> ;

template <class Operation, class T>
binder1st<Operation> bind1st (const Operation&, const T&);

template <class Operation>
class binder2nd : public unary_function<typename
Operation::first_argument_type,
typename Operation::result_type> ;

template <class Operation, class T>
binder2nd<Operation> bind2nd (const Operation&, const T&);

DESCRIPTION
Because so many functions provided by the standard library take other
functions as arguments, the library includes classes that let you
build new function objects out of old ones. Both bind1st() and
bind2nd() are functions that take as arguments a binary function
object f and a value x, and return, respectively, classes binder1st
and binder2nd. The underlying function object must be a subclass of
binary_function.

Class binder1st binds the value to the first argument of the binary
function, and binder2nd does the same thing for the second argument of
the function. The resulting classes can be used in place of a unary
predicate in other function calls.

For example, you could use the count_if algorithm to count all
elements in a vector that are less than or equal to 7, using the
following:

count_if (v.begin, v.end, bind1st(greater<int> (),7), littleNums)

This function adds one to littleNums each time the predicate is true,
i.e., each time 7 is greater than the element.

INTERFACE
// Class binder1st

template <class Operation>
class binder1st
: public unary_function<typename
Operation::second_argument_type,
typename Operation::result_type>
{
public:

typedef typename unary_function<typename
Operation::second_argument_type, typename
Operation::result_type>::argument_type argument_type;
typedef typename unary_function<typename
Operation::second_argument_type, typename
Operation::result_type>::result_type result_type;

binder1st(const Operation&,
const typename Operation::first_argument_type&);
result_type operator() (const argument_type&) const;
};

// Class binder2nd
template <class Operation>
class binder2nd
: public unary_function<typename
Operation::first_argument_type,
typename Operation::result_type>
{
public:
typedef typename unary_function<typename
Operation::first_argument_type, typename
Operation::result_type>::argument_type argument_type;
typedef typename unary_function<typename
Operation::first_argument_type, typename
Operation::result_type>::result_type result_type;

binder2nd(const Operation&,
const typename Operation::second_argument_type&);

- 2 - Formatted: December 23, 2008

bind1st(3C++) Rogue Wave Software bind1st(3C++)
- -

20 Mar 1996

result_type operator() (const argument_type&) const;
};

// Creator bind1st

template <class Operation, class T>
binder1st<Operation> bind1st (const Operation&, const T&);

// Creator bind2nd

template<class Operation, class T>
binder2nd <Operation> bind2nd(const Operation&, const T&);

EXAMPLE
//

// binders.cpp
//
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream.h>
int main()
{
typedef vector<int>::iterator iterator;
int d1[4] = {1,2,3,4};
//
// Set up a vector
//
vector<int> v1(d1,d1 + 4);
//
// Create an 'equal to 3' unary predicate by binding 3 to
// the equal_to binary predicate.
//
binder1st<equal_to<int> > equal_to_3 =
bind1st(equal_to<int>(),3);
//
// Now use this new predicate in a call to find_if
//
iterator it1 = find_if(v1.begin(),v1.end(),equal_to_3);
//
// Even better, construct the new predicate on the fly
//
iterator it2 =
find_if(v1.begin(),v1.end(),bind1st(equal_to<int>(),3));
//
// And now the same thing using bind2nd 20 Mar 1996

// Same result since == is commutative
//
iterator it3 =
find_if(v1.begin(),v1.end(),bind2nd(equal_to<int>(),3));
//
// it3 = v1.begin() + 2
//
// Output results
//
cout << *it1 << " " << *it2 << " " << *it3 << endl;
return 0;
}

Output : 3 3 3
Waiting4you 2008-12-23
  • 打赏
  • 举报
回复
你用的是什么版本?我在BCB2009 Update2上试了没出错。

struct Object{
DWORD GetObjID() const
{
return 0;
}
};

struct ObjectEqualID : public std::binary_function<Object &, DWORD, bool>
{
bool operator ()(Object const& obj, DWORD dwObjID) const
{
return obj.GetObjID() == dwObjID;
}
};

void __fastcall TForm1::FormCreate(TObject *Sender)
{
typedef std::vector<Object> vec_objs;
typedef vec_objs::iterator Object_Iter;
DWORD dwObjID = 0;
vec_objs objs;

//bool bt = std::bind2nd(ObjectEqualID(), dwObjID)( Object() );

Object_Iter p = std::remove_if(objs.begin(), objs.end(), std::bind2nd(ObjectEqualID(), dwObjID));
}
//---------------------------------------------------------------------------
内容概要:本文针对复杂威胁环境下多无人机的协同路径规划问题,提出一种基于多段杜宾斯(Dubins)路径的优化方法,旨在实现高动态、高风险场景无人机群的安全、高效与协同飞行。研究充分考虑无人机的实际飞行约束,如最小转弯半径与连续曲率要求,采用杜宾斯曲线构建平滑且符合动力学特性的路径段,并结合优化算法对多机路径进行协同规划,有效规避静态威胁区域与动态障碍物,避免飞行器间发生碰撞。方案在Matlab平台上完成仿真验证,结果表明该方法能够在城市、军事等复杂环境实现多无人机系统的路径最短化、能耗最低化、安全性最大化与实时性兼顾的多目标优化,具有较强的工程应用潜力。; 适合人群:具备无人机控制、路径规划或智能优化算法基础的科研人员与工程技术人员,特别适用于自动化、航空航天、机器人及相关领域的研究生、高校教师及工业界研发人员。; 使用场景及目标:①应用于复杂城市、战场等高威胁环境下的多无人机协同任务,如侦察监视、应急救援、集群打击与编队巡航;②为解决多无人机系统的动态避障、冲突消解、路径平滑与资源协同分配等关键技术问题提供理论依据与算法实现参考;③帮助研究人员深入理解Dubins路径在多智能体协同运动规划的建模方式与优化机制,推动其在无人系统自主导航的实际落地。; 阅读建议:建议读者结合提供的Matlab代码深入研读算法实现流程,重点分析威胁建模策略、多机冲突协调机制以及多目标代价函数的设计思路,可通过调整环境参数与优化权重在仿真观察路径生成效果,从而加深对协同决策、运动学约束与全局优化之间耦合关系的理解。
内容概要:本文围绕“基于飞机配电优化负荷管理系统研究”展开,利用Matlab代码实现相关建模仿真与优化分析,旨在提升飞机配电系统的效率与可靠性。研究重点针对飞机电力系统的动态负荷分配问题,构建了综合考虑电源容量限制、负载优先级划分、供电安全性、能量消耗最小化及系统冗余能力的多约束优化模型。通过引入先进智能优化算法对模型进行高效求解,实现了对机载关键与非关键设备的科学化、智能化供电管理。文详细展示了算法迭代过程、收敛性分析及不同工况下的仿真结果,验证了该方法在降低整体能耗、均衡电力负载、增强系统稳定性以及应对突发用电需求等方面的优越性能,为现代民用与军用航空器电力系统的自主决策与健康管理提供了坚实的理论支撑与可行的技术路径。; 适合人群:具备电力系统、自动化或航空航天工程背景,熟练掌握Matlab编程语言,从事飞机电气系统设计、航空器能源管理、智能优化算法应用或相关领域研究的科研人员、工程师及研究生。; 使用场景及目标:①应用于新型飞机电气系统的设计与仿真验证,优化机载设备的供电策略与能量管理逻辑;②为复杂封闭电力系统(如舰船、空间站)的负荷调度与应急电源管理提供可借鉴的解决方案,以提升系统整体能效、安全等级与运行韧性。; 阅读建议:建议结合提供的Matlab代码深入理解优化模型的数学建模过程、约束条件的程序化表达及智能算法的具体实现细节,重点关注目标函数的设计思路、权重系数的选取对优化结果的影响,并可尝试将模型拓展至多目标优化、实时滚动优化或考虑设备故障预测的主动负荷管理等更复杂的应用场景。

13,874

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧