从构造函数参数的组合生成变量类型的对象

艾瑟夫·斯普尔伯

假设我有类型AB有构造函数A(int a, double b, std::string c)B(double a, int b)

我知道如何定义一个实例化AB通过可变参数模板实例化的函数

有没有什么方法可以设计一个函数/宏/类型,以便TT的构造函数参数提供类型和一系列可能的矢量,从而为我提供所有可能的对象?

例如,如果我使用这个神奇的构造,<A, {2, 5, 6}, {2.44, 3.14}, {"yes", "no"}>它应该提供对象:

A(2, 2.44, "yes")
A(2, 2.44, "no")
A(2, 3.14, "yes")
...
A(6, 3.14, "no")

相同的东西应该适用于B任何其他类型,而不必重新构造神奇的构造。

例如,这在Python中超级简单,但我不知道在C ++中是否可行。

Yakk-亚当·内夫罗蒙特

std::experimental::array_view用于提高效率。您可以std::vector花费一些运行时成本来替换它,或者以一些清晰的代价来替换一对迭代器/指针。

template<class T>
using array_view = std::experimental::array_view<T>;

using indexes = array_view<std::size_t>;

这将遍历每个元素的叉积,<分别对应索引中的索引。所以{3,3,2}作为is迭代{0,0,0}然后{0,0,1}一路{2,2,1}

template<class F>
void for_each_cartesian_product(
  indexes is,
  F&& f,
  std::vector<std::size_t>& result
) {
  if (is.empty()) {
    f(result);
    return;
  }
  auto max_index = is.front();
  for (std::size_t i = 0; i < max_index; ++i) {
    result.push_back(i);
    for_each_cartesian_product( {is.begin()+1, is.end()}, f, result );
    result.pop_back();
  }
}
template<class F>
void for_each_cartesian_product(
  indexes is,
  F&& f
) {
  std::vector<size_t> buffer;
  for_each_cartesian_product( is, f, buffer );
}

然后我们就填充索引:

template<class...Ts>
std::vector<std::size_t> get_indexes( std::vector<Ts> const&... vs ) {
  return {vs.size()...};
}

接下来,我们只需要接受参数,将其放入向量中,然后使用索引从每个向量中获取元素并将它们传递A给构造即可。

template<class T, std::size_t...Is, class...Args>
std::vector<T> make_stuff( std::index_sequence<Is...>, std::vector<Args>const&... args ) {
  std::vector<T> retval;
  for_each_cartesian_product(
    get_indexes(args...),
    [&](auto&& index){
      retval.emplace_back( args[ index[Is] ]... );
    }
  );
  return retval;
}
template<class T, class...Args>
std::vector<T> make_stuff( std::vector<Args>const&... args ) {
  return make_stuff<T>( std::index_sequence_for<Args...>{}, args... );
}

鲍勃是你叔叔

A生成的S可以被移动。

也可以在编译时使用已知的数组执行此操作。

index_sequence_forindex_sequence是C ++ 14,但易于在C ++ 11中实现。堆栈溢出有很多例子。

上面的代码尚未编译。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将对象类型作为参数传递给构造函数并向其强制转换变量(JAVA)?

是否可以从Java中的对象构造函数中删除泛型类型参数?

为什么不能将GregorianCalendar用作对象类型作为构造函数参数?

获取函数/类构造函数的参数类型

Intellij代码完成,显示方法/构造函数的参数类型和变量名称

如何检查无参数构造函数的类型?

构造函数,模板和非类型参数

SFINAE条件和构造函数参数类型

为什么不能使用此构造函数参数构造此用户定义类型的对象?

成员变量的类型应取决于构造函数参数的类型

在方法/构造函数中限制“类型”参数

传递枚举类型作为构造函数参数

一个构造函数可以照顾多种类型的不同对象参数吗?

获取构造函数的参数类型作为元组

对象的构造函数作为函数参数

如何构造std :: variant类型对象,其本身的Templated和构造函数转发参数

在Python中的对象实例化期间使用构造函数参数变量名称?

类型构造函数参数推断

具有类型参数的派生构造函数

泛型类型作为构造函数参数

EnumConverter构造函数如何获取类型参数

错误的构造函数参数类型,PySide

无法创建生成类型的实例:未为此对象定义无参数构造函数

PHPStan - 更改构造函数参数的类型

如何使用 kotlinpoet 生成具有单个类型参数的 Kotlin“Unit”类型的构造函数参数?

如何使用对象类型作为方法/构造函数的参数?

从具有可变参数模板构造函数的类型构造 std::function 对象

JS - URLSearchParam 构造函数参数类型问题

“类型错误:FormData 构造函数:参数 1 不是对象。”