#include <cstdio>
class builtin_pack
{
long v[4];
public:
builtin_pack ( long v1, long v2, long v3, long v4 ) : v{v1, v2, v3, v4} {}
void builtin_op()
{
printf ( "%lx,%lx,%lx,%lx\n", v[0], v[1], v[2], v[3] );
};
template<typename Func, typename... Targs>
void builtin_apply ( Func f, Targs ... t )
{
for ( int i = 0; i < 4; i++ )
{
v[i] = f ( t.v[i]... );
}
}
};
class pack : builtin_pack
{
public:
pack ( long v1, long v2, long v3, long v4 ) : builtin_pack ( v1, v2, v3, v4 ) {}
template<typename Func, typename... Targs>
pack& apply ( Func f, Targs ... t )
{
this->builtin_apply ( f, t... );
return *this;
}
void op()
{
this->builtin_op();
}
};
int main()
{
pack p1{0xff, 0x0f, 0xf0, 0x06}, p2{0x0f00, 0xf000, 0x6700, 0xff00};
pack p3{0x12340000, 0x56780000, 0x45120000, 0xdead0000};
p3.apply ( [] ( long i, long j, long k )->long{return i | j | k;}, p1, p2, p3 );
p3.op();
return 0;
}
That code compiles with an error:
main.cpp:17:24: error: cannot cast 'pack' to its private base class 'builtin_pack'
v[i] = f ( t.v[i]... );
^
main.cpp:29:15: note: in instantiation of function template specialization 'builtin_pack::builtin_apply<(lambda
at main.cpp:42:16), pack, pack, pack>' requested here
this->builtin_apply ( f, t... );
^
main.cpp:42:8: note: in instantiation of function template specialization 'pack::apply<(lambda at
main.cpp:42:16), pack, pack, pack>' requested here
p3.apply ( [] ( long i, long j, long k )->long{return i | j | k;}, p1, p2, p3 );
^
main.cpp:22:14: note: implicitly declared private here
class pack : builtin_pack
^~~~~~~~~~~~
main.cpp:17:26: error: 'v' is a private member of 'builtin_pack'
v[i] = f ( t.v[i]... );
^
main.cpp:22:14: note: constrained by implicitly private inheritance here
class pack : builtin_pack
^~~~~~~~~~~~
main.cpp:5:10: note: member is declared here
long v[4];
^
2 errors generated.
What I want to do is to implement a mapping method with a custom (lambda) function (called 'apply'). It works readily when the hierarchy of private implementor-public wrapper is absent, so when the array v
is just in the class pack
, it compiles and runs as expected. However, it does not work when data is stored in a private-inherited class.
The structure of the class is a private implementor class along with a wrapper class, and in the middle I encountered this error.
Have I used the variadic template the wrong way? Or is there a workaround available?
(Sorry for my poor expression as I am a newbie in C++ and stackoverflow and non-native speaker of English, and modification or suggestion of the question is welcomed as long as the original intention is reserved!)
Variadic function templates in C++. Variadic templates are template that take a variable number of arguments. Variadic function templates are functions which can take multiple number of arguments.
The contents of the variadic template arguments are called parameter packs. These packs will then be unpacked inside the function parameters. For example, if you create a function call to the previous variadic function template... Syntax - the sizeof... operator (sizeof...):
Although the D programming language also provides the use of variadic templates, only variadic templates offered by C++11 standard will be covered here, so knowledge of D programming language's variadic templates is not required in order to read & understand this article.
Douglas Gregor and Jaakko Järvi came up with this feature for C++. Variadic arguments are very similar to arrays in C++. We can easily iterate through the arguments, find the size (length) of the template, can access the values by an index, and can slice the templates too.
Your problem is that with private inheritance, you cannot convert from pack*
to builtin_pack*
(outside of pack
, that is). If you do cast it, the code compiles, although I'm not sure if this is what you were after:
template<typename Func, typename... Targs>
pack& apply ( Func f, Targs ... t )
{
this->builtin_apply ( f, static_cast<builtin_pack&&>(t)... );
return *this;
}
live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With