我正在编写一个C ++ 11库,用户需要在其中指定要使用的struct
和要使用的元素(按顺序)。例如:
// Declaration
struct MyData{ double x, y ,z;};
...
// Use
MyClass<MyData, y, x> myobj;
MyData mydata;
myobj.set(mydata);
...
然后,MyClass
应生成迭代参数包的不同函数,但将参数视为表达式。为此,我声明了一个带参数包的类:
template<class T, class ... G>
class MyClass{
std::vector<double*> var;
public:
Test();
void set(T const& var_);
};
然后我无法弄清楚如何生成set()
函数。行为应该类似于以下伪代码:
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);
}
在MyClass<MyData,y,x>
的情况下会生成:
...
*var[0] = var_.y;
*var[1] = var_.x;
...
答案 0 :(得分:3)
在我看来,你正在寻找一种方法来将一个可变的指针序列传递给结构/类的成员作为模板参数以及使用它们的方法。
将指向可变结构的指针序列作为模板参数传递给结构/类成员的语法如下
template <typename T, typename U, U T::* ... Ms>
struct MyClass
{ /* something */ };
但是,在您的情况下,您已将U
类型修改为double
,因此您可以简化如下
template <typename T, double T::* ... Ms>
struct MyClass
{ /* something */ };
要在set()
中获取正确的值,您可以按照以下方式进行操作
void set (T const & v0)
{
using unused = int[];
(void)unused { 0, (var.emplace_back(v0.*Ms), 0) ... };
}
请注意,为简化起见,我在var
s的向量中更改了double
向量,而不是指向đouble
s的指针。
以下是完整(简化)示例
#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;
}
答案 1 :(得分:0)
另一种方法是让用户指定一个元组和索引:
struct MyData : std::tuple<double, double, double> {
enum Names { X, Y, Z }; // Named indexes.
};
template<class T, size_t... Indexes>
class MyClass {
std::vector<double*> var;
public:
void set(T const& t) {
auto unused = { (*var[Indexes] = std::get<Indexes>(t), 1)... };
static_cast<void>(unused);
}
};
int main() {
MyClass<MyData, MyData::X, MyData::Y> myobj;
MyData mydata;
myobj.set(mydata);
}