I'm writing a C++11 library in which the user needs to specify a struct
to use and the elements to be used (in order). For example:
// Declaration
struct MyData{ double x, y ,z;};
...
// Use
MyClass<MyData, y, x> myobj;
MyData mydata;
myobj.set(mydata);
...
Then, MyClass
should generate different functions that iterate through the parameter pack, but considering the parameters as expressions. For that, I declared a class with a parameter pack:
template<class T, class ... G>
class MyClass{
std::vector<double*> var;
public:
Test();
void set(T const& var_);
};
And then I can't figure out how to generate the set()
function. The behavior should be like the following pseudo-code:
template<class T, class ... G>
void Test<T, G...>::set(T const& var_){
unsigned pos = 0;
for(unsigned i =0; i < sizeof...(G); i++)
*var[i] = var_.G(i);
}
Which, in the case of MyClass<MyData,y,x>
would generate:
...
*var[0] = var_.y;
*var[1] = var_.x;
...
In seems to me that your looking a way to pass a variadic sequence of pointer to member of structs/classes as template parameter and a way to use they.
The syntax to pass a variadic sequence of pointer to member of structs/classes as template parameter is the following
template <typename T, typename U, U T::* ... Ms>
struct MyClass
{ /* something */ };
but, in your case, you've fixed the U
type as double
so you can simplify as follows
template <typename T, double T::* ... Ms>
struct MyClass
{ /* something */ };
To take the correct values in set()
you can make somethings as follows
void set (T const & v0)
{
using unused = int[];
(void)unused { 0, (var.emplace_back(v0.*Ms), 0) ... };
}
Observe that, to simplify, I've changed your var
vector in a vector of double
s, not of pointers to đouble
s.
The following is a full (simplified) example
#include <vector>
#include <iostream>
struct MyData
{ double x, y ,z; };
template <typename T, double T::* ... Ms>
struct MyStruct
{
std::vector<double> var;
void set (T const & v0)
{
using unused = int[];
(void)unused { 0, (var.emplace_back(v0.*Ms), 0) ... };
}
};
int main ()
{
MyData md { 1.0, 2.0, 3.0 };
MyStruct<MyData, &MyData::y, &MyData::x> ms;
ms.set(md);
for ( auto const & d : ms.var )
std::cout << d << ' ';
std::cout << std::endl;
}