I have a class hierarchy like this one (this is the actual class but I cleaned it up):
class Notifiable
{
public:
void notify();
}
template <class Exp>
class Batch : public Notifiable
{
public:
void run();
}
void Batch<Exp>::run()
{
done.clear();
generator->resetGeneration();
while(generator->hasMoreParameters())
{
// Lock for accessing active
std::unique_lock<std::mutex> lock(q_mutex, std::adopt_lock);
// If we've less experiments than threads
if (active.size() < threads)
{
Configuration conf = generator->generateParameters();
Exp e(executable, conf);
//std::weak_ptr<Batch<Exp>> bp;
//bp.reset(this);
std::thread t(&Exp::run, e, *this);
std::thread::id id = t.get_id();
active.insert(id);
t.detach();
}
q_control.wait(lock, [this] { return active.size() < threads; } );
}
}
class Experiment
{
public:
void run(Notifiable& caller)
{
do_stuff();
caller.notify();
}
virtual void do_stuff() = 0;
}
class MyExperiment : public Experiment
{
public:
void do_stuff()
{
// do my stuff
}
}
I then instantiate a Batch<MyExperiment>
object and call run()
, using this code:
Batch<ELExperiment> b(pex, options["name"].as<string>(), options["executable"].as<string>());
b.run();
but I get this at compile-time:
In file included from /opt/local/include/gcc47/c++/bits/move.h:57:0,
from /opt/local/include/gcc47/c++/bits/stl_pair.h:61,
from /opt/local/include/gcc47/c++/bits/stl_algobase.h:65,
from /opt/local/include/gcc47/c++/bits/char_traits.h:41,
from /opt/local/include/gcc47/c++/ios:41,
from /opt/local/include/gcc47/c++/ostream:40,
from /opt/local/include/gcc47/c++/iostream:40,
from json2cli/main.cpp:9:
/opt/local/include/gcc47/c++/type_traits: In instantiation of 'struct std::_Result_of_impl<false, false, std::_Mem_fn<void (Experiment::*)(Notifiable&)>, MyExperiment, Batch<MyExperiment> >':
/opt/local/include/gcc47/c++/type_traits:1857:12: required from 'class std::result_of<std::_Mem_fn<void (Experiment::*)(Notifiable&)>(MyExperiment, Batch<MyExperiment>)>'
/opt/local/include/gcc47/c++/functional:1563:61: required from 'struct std::_Bind_simple<std::_Mem_fn<void (Experiment::*)(Notifiable&)>(MyExperiment, Batch<MyExperiment>)>'
/opt/local/include/gcc47/c++/thread:133:9: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Experiment::*)(Notifiable&); _Args = {MyExperiment&, Batch<MyExperiment>&}]'
json2cli/batch.hh:86:46: required from 'void Batch<Exp>::run() [with Exp = MyExperiment]'
json2cli/main.cpp:113:15: required from here
/opt/local/include/gcc47/c++/type_traits:1834:9: error: no match for call to '(std::_Mem_fn<void (Experiment::*)(Notifiable&)>) (MyExperiment, Batch<MyExperiment>)'
In file included from /opt/local/include/gcc47/c++/memory:81:0,
from json2cli/parameterexpression.hh:19,
from json2cli/main.cpp:13:
/opt/local/include/gcc47/c++/functional:525:11: note: candidates are:
/opt/local/include/gcc47/c++/functional:548:7: note: _Res std::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = void; _Class = Experiment; _ArgTypes = {Notifiable&}]
/opt/local/include/gcc47/c++/functional:548:7: note: no known conversion for argument 1 from 'MyExperiment' to 'Experiment&'
/opt/local/include/gcc47/c++/functional:553:7: note: _Res std::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = void; _Class = Experiment; _ArgTypes = {Notifiable&}]
/opt/local/include/gcc47/c++/functional:553:7: note: no known conversion for argument 1 from 'MyExperiment' to 'Experiment*'
/opt/local/include/gcc47/c++/functional:559:2: note: template<class _Tp> _Res std::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Tp&, _ArgTypes ...) const [with _Tp = _Tp; _Res = void; _Class = Experiment; _ArgTypes = {Notifiable&}]
/opt/local/include/gcc47/c++/functional:559:2: note: template argument deduction/substitution failed:
In file included from /opt/local/include/gcc47/c++/bits/move.h:57:0,
from /opt/local/include/gcc47/c++/bits/stl_pair.h:61,
from /opt/local/include/gcc47/c++/bits/stl_algobase.h:65,
from /opt/local/include/gcc47/c++/bits/char_traits.h:41,
from /opt/local/include/gcc47/c++/ios:41,
from /opt/local/include/gcc47/c++/ostream:40,
from /opt/local/include/gcc47/c++/iostream:40,
from json2cli/main.cpp:9:
/opt/local/include/gcc47/c++/type_traits:1834:9: note: cannot convert 'std::declval<Batch<MyExperiment> >()' (type 'Batch<MyExperiment>') to type 'Notifiable&'
It looks like I can't just expect to generalize any Batch<Exp>
into a Notifiable
for function calling. Can you confirm that?
Update sorry, I thought I could avoid dumping all of my code inside the question, but in fact there must be something wrong in the way I spawn the thread for Batch<Exp>::run()
. There are still a couple of details missing, but I don't really think they are related (e.g. how I generate the parameters for the experiment).
Thanks