在未初始化的对象上使用std :: bind是否安全?

时间:2013-01-09 21:59:42

标签: c++ bind

由于我无法正确设计课程,我达到了需要这样的地步:

struct A
{
   A( function< void(string&) cb > ): callback(cb) {}
   function< void(string&) > callback;

   template <std::size_t T>
   void func( string& str) { ... }
}

int main(){
vector<A> items = {
   A( bind( &A::func<1>, items[0], _1) ),
   A( bind( &A::func<2>, items[1], _1) ),
   ...
}

这样安全吗?如果没有,还有其他选择吗?

3 个答案:

答案 0 :(得分:6)

这当然不安全。 items[0]将在初始化items之前进行评估。

这里适当的做法可能就是使用lambda,比如

vector<A> items = {
    A( [&items](string& s){ items[0].func(s); } ),
    A( [&items](string& s){ items[1].func(s); } ),
    ...
}

这仅在初始化期间获取对items的引用,然后仅在实际调用回调时才提取items[0]

或者,您是否可以更改回调以将A&作为参数?如果您的回调类型为std::function<void(A&, string&)>,那么您只需传递&A::func<1>作为回调即可。

答案 1 :(得分:5)

您正在使用[]运算符在构建之前访问vector。这不安全。

我认为你必须在vector中创建非完全初始化的项目,然后再设置bindee。

答案 2 :(得分:0)

main中的代码会创建一个固定大小的向量。如果这实际上是必需的,请使用数组或std::array,并将元素的地址传递给bind来电:

A items[] = {
   A( bind( &A::func<1>, &items[0], _1) ),
   A( bind( &A::func<2>, &items[1], _1) ),
   ...
};

bind返回的函数对象知道如何绑定指向对象的指针和成员函数。