boost库bind的一些用法

本文探讨了C++中使用模板和Boost库实现特定功能的技术,包括成员函数引用、函数对象、函数模板、Boost.Function库的应用等。通过具体代码示例展示了如何高效地操作容器元素、实现状态通知、调用类成员函数、使用Boost.Function处理函数指针和函数对象,以及在不同场景下使用函数模板和函数对象的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::for_each(vect.begin(), vect.end(), std::mem_fun_ref(&class::fun));
std::for_each(vect.begin(), vect.end(), boost::bind(&class::fun, _1));
ptr
std::for_each(vect.begin(), vect.end(), std::mem_fun(&class::fun))
std::for_each(vect.begin(), vect.end(), boost::bind(&class::fun, _1));
std::string surname() const {
 return name_;
}
#include <iostream>
#include <boost/function.hpp>
bool some_func(int i, double d)
{
 return i > d;
}
int main()
{
 boost::function<bool (int, double)> f;
 f = &some_func;
 f(10, 1.1);
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
void print_new_value(int i)
{
 std::cout << "The value has been updated and is now" << i << std::endl;
}
void interested_in_the_change(int i)
{
 std::cout << "Ah, the value has changed." << std::endl;
}
class notifier
{
 typedef void (*function_type)(int);
 std::vector<function_type> vec_;
 int value_;
public:
 void add_observer(function_type t)
 {
  vec_.push_back(t);
 }
 void change_value(int i)
 {
  value_ = i;
  for (std::size_t i=0; i<vec_.size(); ++i)
  {
   (*vec_[i]) (value_);
  }
 }
};
int main()
{
 notifier n;
 n.add_observer(&print_new_value);
 n.add_observer(&interested_in_the_change);
 n.change_value(42);
}


--------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
class some_class
{
public:
 void do_stuff(int i) const
 {
  std::cout << "OK, Stuff is done. " << i << std::endl;
 }
};
int main()
{
 //boost::function<void(some_class, int)> f;
 //f=&some_class::do_stuff;
 //f(some_class(), 2);
 //boost::function<void(some_class&, int)> f;
 //f=&some_class::do_stuff;
 //some_class s;
 //f(s, 2);
 boost::function<void(some_class*, int)> f;
 f = &some_class::do_stuff;
 some_class s;
 f(&s, 3);
}
------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
class keepint_state
{
 int total_;
public:
 keepint_state():total_(0) {}
 int operator()(int i)
 {
  total_ += i;
  return total_;
 }
 int total() const
 {
  return total_;
 }
};
int main()
{
 keepint_state ks;
 boost::function<int(int)> f1;
 //f1 = ks;
 f1 = boost::ref(ks);
 boost::function<int(int)> f2;
 //f2 = ks;
 f2 = boost::ref(ks);
 std::cout << "The current total is " << f1(10) << std::endl;
 std::cout << "The current total is " << f2(10) << std::endl;
 std::cout << "After adding 10 two times, the total is " << ks.total() << std::endl;
}


 data my(1, 11);
 if(std::binary_search(vec.begin(), vec.end(), my,
  boost::bind<bool>(
  std::less<unsigned int>(),
  boost::bind(&data::a_,_1),
  boost::bind(&data::a_,_2)
  )))
 {
 int a =0;
 }
 iter = std::lower_bound(vec.begin(), vec.end(), my,
  boost::bind<bool>(
  std::less<unsigned int>(),
  boost::bind(&data::a_,_1),
  boost::bind(&data::a_,_2)
  ));
 if(iter!=vec.end())
 {
  std::cout << "========" << std::endl;
  std::cout << (*iter).a_ << " " << (*iter).b_ << std::endl;
 }
 iter = std::upper_bound(vec.begin(), vec.end(), my,
  boost::bind<bool>(
  std::less<unsigned int>(),
  boost::bind(&data::a_,_1),
  boost::bind(&data::a_,_2)
  ));
 if(iter!=vec.end())
 {
  std::cout << "========" << std::endl;
  std::cout << (*iter).a_ << " " << (*iter).b_ << std::endl;
 }

  std::sort(
   vect_enter_copy_.begin(),
   vect_enter_copy_.end(),
   boost::bind<bool>(
   std::less<int>(),
   boost::bind(&enter_copy_data::id_, _1),
   boost::bind(&enter_copy_data::id_, _2)));

  //method 1
  //ptr_vect_type::iterator iter = std::find_if(
  // vect_enter_copy_.begin(),
  // vect_enter_copy_.end(),
  // boost::bind<bool>(
  // std::equal_to<int>(),
  // copy_id,
  // boost::bind(&enter_copy_data::get_id, _1)));
  //if(iter != vect_enter_copy_.end())
  // ret = (*iter).live_time_;
  //enter_copy_data data(copy_id);
  //method 2
  //ptr_vect_type::iterator iter = std::lower_bound(vect_enter_copy_.begin(), vect_enter_copy_.end(), data,
  // boost::bind<bool>(
  // std::less<unsigned int>(),
  // boost::bind(&enter_copy_data::id_, _1),
  // boost::bind(&enter_copy_data::id_, _2)
  // ));
  //if(iter!=vect_enter_copy_.end()) //{
  // ret = (*iter).live_time_;
  //}


#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/ptr_container/ptr_map.hpp>
struct my_class
{
 my_class()
 {
  std::cout << "my_class()" << std::endl;
 }
 ~my_class()
 {
  std::cout << "~my_class()" << std::endl;
 }
 my_class(const my_class& other)
 {
  a_ = other.a_;
  b_ = other.b_;
  std::cout << "(const my_class& other)" << std::endl;
  //return *this;
 }
 my_class & operator = (const my_class& rhs)
 {
  a_ = rhs.a_;
  b_ = rhs.b_;
  std::cout << "my_class & operator =" << std::endl;
  return *this;
 }
 int a_;
 int b_;
};
int main()
{
 boost::ptr_vector< my_class > vec;
 std::map<int, boost::ptr_vector< my_class > > mp;
 {
  my_class *my1 = new my_class();
  my1->a_ = 1;
  my1->b_ = 2;
  vec.push_back(my1);
  my_class *my2 = new my_class();
  my2->a_ = 11;
  my2->b_ = 22;
  vec.push_back(my2);
 }
 mp.insert(std::make_pair(1,vec));
 int index = 0;
 for(auto iter = mp.begin(); iter != mp.end(); ++iter)
 {
  for(auto i = (*iter).second.begin(); i != (*iter).second.end(); ++i, ++index)
   std::cout << "a_: " << (*iter).second.at(index).a_ << "b_: " << (*iter).second.at(index).b_ << std::endl;;
 }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/bind.hpp>


using namespace std;


struct Element
{
int a;
int b;
};


class my_test
{
public:
my_test()
{


}

void ReferenceFn( Element & e );


void PointerFn( Element * e );


void Function();


void fn(int a, int b)
{
cout << a << b << endl;
}


void fn1()
{
vector< int > vec;
vec.push_back( 1 );
vec.push_back( 2 );
vec.push_back( 3 );


std::for_each(
vec.begin(), 
vec.end(), 
boost::bind(&my_test::fn, this, 5, _1)
);
}
};


void my_test::ReferenceFn( Element & e ) {  }


void my_test::PointerFn( Element * e ) { }


void my_test::Function()
{
std::vector< Element * > elements;
// add some elements...


// This works, as the argument is a pointer type
std::for_each( elements.begin(), elements.end(),
boost::bind( &my_test::PointerFn, boost::ref(*this), _1 ) );


// This fails (compiler error), as the argument is a reference type
//std::for_each( elements.begin(), elements.end(),
// boost::bind( &my_test::ReferenceFn, boost::ref(*this), _1 ) );


std::for_each( boost::make_indirect_iterator(elements.begin()), 
               boost::make_indirect_iterator(elements.end()),
               boost::bind( &my_test::ReferenceFn, boost::ref(*this), _1 ) );
}
int main()
{
my_test test;
test.fn1();


return 0;
}
### Boost.Bind 的基本概念 `boost::bind` 是用于创建可调用对象的强大工具,允许绑定函数、成员函数以及带有一组固定参数的仿函数。通过 `boost::bind` 可以灵活处理回调机制和其他需要延迟执行的情景。 ### 基本语法结构 #### 绑定简单函数 对于简单的全局函数或静态成员函数,可以直接使用 `boost::bind` 进行封装: ```cpp #include <iostream> #include <boost/bind.hpp> // 定义一个普通的二元加法函数 int add(int a, int b) { return a + b; } int main() { auto bound_add = boost::bind(add, 2, _1); std::cout << "Result of adding 3 to 2 is: " << bound_add(3) << std::endl; // 输出应为: Result of adding 3 to 2 is: 5 } ``` 此处 `_1` 表示占位符,代表后续传递给返回的对象的第一个实际参数[^1]。 #### 成员函数绑定 当涉及到类成员函数时,则需提供实例指针作为第一个实参: ```cpp class MyClass { public: int multiply(int factor) const { return value * factor; } private: static constexpr int value = 7; }; MyClass obj; auto multiplier = boost::bind(&MyClass::multiply, &obj, _1); std::cout << "Multiplying by 8 gives us: " << multiplier(8) << std::endl; // 结果应该是 Multiplying by 8 gives us: 56 ``` 这里展示了如何将成员函数与特定对象关联起来,并设置了一个占位符以便稍后传入乘数。 #### 处理多参数情况 如果目标函数接受多个参数,可以利用额外的占位符来指定哪些位置由外部输入填充: ```cpp bool compare_strings(const std::string& s1, const string& s2) { return s1.size() >= s2.size(); } using namespace boost::placeholders; // 创建比较器,其中s1总是固定的字符串"hello" auto comp_with_hello = boost::bind(compare_strings, "hello", _1); if (comp_with_hello("world")) { std::cout << "'hello' has equal or greater length than 'world'" << std::endl; } else { std::cout << "'hello' does not have enough characters compared with 'world'" << std::endl; } ``` 此片段说明了如何预先设定某些参数而保留其他参数开放供以后赋值。 ### 特殊场景下的注意事项 - **标准调用约定支持** 为了兼容不同平台上的特殊调用约定(如 Windows 下常见的 __stdcall),可以在包含 `<boost/bind.hpp>` 文件前定义宏 `BOOST_BIND_ENABLE_STDCALL` 来启用相应特性[^4]。 - **异常安全保证** 在现代 C++ 中推荐尽可能采用 noexcept 规范编写代码;因此,在涉及可能抛出异常的操作时应当特别小心。有关具体实践建议,请参考相关资料了解如何正确运用 noexecpt 关键字[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值