how to create (initialize) a std::tuple from an array when the constructors have the same argument type (a file path)

时间:2022-12-25 12:53:41

I have some classes all having a constructor that takes a file path. I would like to create a std::tuple of them from the argv argument in the main function. Here is a sketch

我有一些类都有一个采用文件路径的构造函数。我想从main函数中的argv参数创建一个std :: tuple。这是一个草图

class A { 
  public:
  A(const char *); // Taking a file path
};

class B {
  public:
  B(const char *); // Taking a file path
};

int main(int argc, char* argv[]) {
  auto tup(myCreateTuple<A, B, A>(argc, argv)); 
  // myCreateTuple would in this case use argv[1], argv[2]
  // and argv[3] to create A(argv[1]), B(argv[2]) and A(argv[3]). 
  // argc is just passed along to verify that argv is long enough.
  // tup would have of the type std::tuple<A ,B, A>
}

The order in which the tuple members are created is not important (i.e. the execution order of the constructors is allowed to be undefined). Do you have an idea of how to implement myCreateTuple?

创建元组成员的顺序并不重要(即,允许构造函数的执行顺序未定义)。你知道如何实现myCreateTuple吗?

I guess it would be possible to avoid myCreateTuple all together and instead use

我想有可能一起避免myCreateTuple而是使用

std::tuple<A, B, A> tup{ A(argv[1]), B(argv[2]), A(argv[3]) };

but that would be a less generic solution.

但这将是一个不太通用的解决方案。

2 个解决方案

#1


3  

Using <redi/index_tuple.h> to provide a compile-time integer sequence that produces the array indices in a pack expansion:

使用 提供编译时整数序列,在序列扩展中生成数组索引:

#include <tuple>
#include <assert.h>
#include <redi/index_tuple.h>

template<typename... T, unsigned... I>
inline std::tuple<T...>
myCreateTuple_impl(char** argv, redi::index_tuple<I...>)
{
  return std::tuple<T...>(argv[I+1]...);
}

template<typename... T>
inline std::tuple<T...>
myCreateTuple(int argc, char** argv)
{
  assert(argc > sizeof...(T));
  return myCreateTuple_impl<T...>(argv, redi::to_index_tuple<T...>());
}

#2


1  

Create a compile time sequence of ints of values 1 2 3 (or 0 1 2) from the number of types you pass in.

根据传入的类型数创建值为1 2 3(或0 1 2)的整数的编译时序列。

Then reference both the sequence as an index into the array and setters into the tuple using ... syntax. Or put the ... in a constructor call directly with the int sequence dereferencing the array.

然后使用...语法将序列作为索引引入数组并将setter引用到元组中。或者在构造函数调用中直接使用取消引用数组的int序列。

#1


3  

Using <redi/index_tuple.h> to provide a compile-time integer sequence that produces the array indices in a pack expansion:

使用 提供编译时整数序列,在序列扩展中生成数组索引:

#include <tuple>
#include <assert.h>
#include <redi/index_tuple.h>

template<typename... T, unsigned... I>
inline std::tuple<T...>
myCreateTuple_impl(char** argv, redi::index_tuple<I...>)
{
  return std::tuple<T...>(argv[I+1]...);
}

template<typename... T>
inline std::tuple<T...>
myCreateTuple(int argc, char** argv)
{
  assert(argc > sizeof...(T));
  return myCreateTuple_impl<T...>(argv, redi::to_index_tuple<T...>());
}

#2


1  

Create a compile time sequence of ints of values 1 2 3 (or 0 1 2) from the number of types you pass in.

根据传入的类型数创建值为1 2 3(或0 1 2)的整数的编译时序列。

Then reference both the sequence as an index into the array and setters into the tuple using ... syntax. Or put the ... in a constructor call directly with the int sequence dereferencing the array.

然后使用...语法将序列作为索引引入数组并将setter引用到元组中。或者在构造函数调用中直接使用取消引用数组的int序列。