0

I want to pass to boost::bind a templated object, but g++ always yield an error. I have found how to pass a templated function, but is it possible to pass a templated object?.

Here's the code.

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>

#include "tbb/tick_count.h"

#include <iostream>
#include <vector>

template<class T>
class LockedVector {
private:
  std::vector<T> v;
  boost::mutex vector_mutex;
public:
  LockedVector(void):v(){}
  LockedVector(const unsigned int& n){
    v.reserve( n );
  }
  void Push(const T& t) {
    boost::mutex::scoped_lock lock( vector_mutex );
    v.push_back(t);
  }
  void Print(std::ostream& O) {
    for(unsigned int i(0);i<v.size();++i){
      O << v[i] << " ";
    }
    std::cout << std::endl;
  }
};

template<class T>
void AddToGlobalVector(LockedVector<T>& lv, unsigned int& start, const unsigned int& end, double& time)  {
  tbb::tick_count t0( tbb::tick_count::now() );
  for(;
  start < end;
  ++start) {
   lv.Push( (T)start );
  }
  time = (tbb::tick_count::now()-t0).seconds();
};

int main(void) {
  double time_t1(0.0);
  double time_t2(0.0);
  LockedVector<unsigned int> global;
  boost::thread t1(&AddToGlobalVector, global, (unsigned int)1, (unsigned int)10, boost::ref(time_t1) );
  boost::thread t2(&AddToGlobalVector, global, (unsigned int)11, (unsigned int)20, boost::ref(time_t2) );
  t1.join();
  t2.join();
  global.Print(std::cout);
  std::cout << "First thread(seconds): " << time_t1 << std::endl;
  std::cout << "Second thread(seconds): " << time_t2 << std::endl; 
}

And here's the g++ output:

main.cpp: In function ‘int main()’:
main.cpp:58: error: no matching function for call to ‘boost::thread::thread(<unresolved overloaded function type>, LockedVector<unsigned int>&, unsigned int, unsigned int, const boost::reference_wrapper<double>)’
/usr/include/boost/thread/detail/thread.hpp:199: note: candidates are: boost::thread::thread(boost::detail::thread_move_t<boost::thread>)
/usr/include/boost/thread/detail/thread.hpp:147: note:                 boost::thread::thread()
/usr/include/boost/thread/detail/thread.hpp:118: note:                 boost::thread::thread(boost::detail::thread_data_ptr)
/usr/include/boost/thread/detail/thread.hpp:108: note:                 boost::thread::thread(boost::thread&)
main.cpp:59: error: no matching function for call to ‘boost::thread::thread(<unresolved overloaded function type>, LockedVector<unsigned int>&, unsigned int, unsigned int, const boost::reference_wrapper<double>)’
/usr/include/boost/thread/detail/thread.hpp:199: note: candidates are: boost::thread::thread(boost::detail::thread_move_t<boost::thread>)
/usr/include/boost/thread/detail/thread.hpp:147: note:                 boost::thread::thread()
/usr/include/boost/thread/detail/thread.hpp:118: note:                 boost::thread::thread(boost::detail::thread_data_ptr)
/usr/include/boost/thread/detail/thread.hpp:108: note:                 boost::thread::thread(boost::thread&)

Thanks.

EDIT:

Well, ok. I have found how to do it.

boost::thread t1(&AddToGlobalVector<unsigned int>, boost::ref(global), (unsigned int)1, (unsigned int)10, boost::ref(time_t1) );
boost::thread t2(&AddToGlobalVector<unsigned int>, boost::ref(global), (unsigned int)11, (unsigned int)20, boost::ref(time_t2) );

Also, I had to move the boost::mutex out of the LockedVector class, since it's not movable and boost::bind complains.

So the question now is if it's possible to maintain the mutex inside the class.

Adri C.S.
  • 2,909
  • 5
  • 36
  • 63
  • 2
    What versions of GCC and Boost are you using? Your code (incorporating your edit) compiled for me using Clang 3.1 (in C++11 mode) and Boost 1.49. You might need to update your tools and Boost library. You should post the errors you're getting instead of just saying "boost::bind complains". How are we supposed to guess what those errors are? – Emile Cormier Jul 04 '12 at 04:00

1 Answers1

0

You may want to declare a move constructor to LockedVector, that instantiates a new mutex instead of trying to move it.

LockedVector(LockedVector<T> && lv) : v(lv.v) {}

Note that I am going fully speculative here, as I don't have access to a compiler.

Raphaël Saint-Pierre
  • 2,498
  • 1
  • 19
  • 23