I am sharing with you an issue that I got with a class using variadic function parameters. It is the class Thread shown in the following code. It is a wrapper of std::thread in order to use the function pattern.
I wanted to use polymorphism with this function in inheriting the class Thread into a new class, Functor, but gcc returns the errors bellow:
#include <thread>
#include <iostream>
using namespace std;
template<class... Args>
class Thread
{
public:
virtual void operator()(Args...) = 0;
void run(Args... args)
{
std::thread t(std::forward< Thread<Args...> >(*this), std::forward<Args>(args)...);
t.join();
}
};
template<class... Args>
class Functor : public Thread<Args...>
{
public:
// generates the errors bellow
virtual void operator()(Args... /*args*/)
{
}
// doesnot work since the pure virtual function wants another prototype of function.
// void operator()(int)
// {
// }
};
int main()
{
int a = 12;
Functor<int> f;
f.run(ref(a));
return 0;
}
from t-Thread-args2.cpp:1: /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple: In instantiation of ‘struct std::_Head_base, false>’: /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:215:12: required from ‘struct std::_Tuple_impl, int>’ /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:507:11: required from ‘class std::tuple, int>’ /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/functional:1601:39: required from ‘struct std::_Bind_simple(int)>’ /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/thread:133:9: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Thread; _Args = {int}]’ t-Thread-args2.cpp:14:83: required from ‘void Thread::run(Args ...) [with Args = {int}]’ t-Thread-args2.cpp:42:17: required from here /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:166:13: error: cannot declare field ‘std::_Head_base, false>::_M_head_impl’ to be of abstract type ‘Thread’ t-Thread-args2.cpp:7:7: note: because the following virtual functions are pure within ‘Thread’: t-Thread-args2.cpp:10:18: note: void Thread::operator()(Args ...) [with Args = {int}]
I dont really understand the error since the pure virtual function was well defined in the deriveted class. However, in moving the function run() into the derivated class (Functor) it works.
Thanks in advance, Caner
std::forward
doesn't make sense. It makes sense for function template, but in your coderun()
is not a function template. – Nawazstd::forward
doesn't make sense here because its argument is always*this
, i.e. always an lvalue. – jogojapanstd::forward
is almost always lvalue, as it usually has a name. – Nawaz