是否有任何语法可以让我在模板参数包的参数之间分发非类型参数包,并期望非类型包(不同大小)?由于这非常令人困惑,我相信一个例子可能有助于澄清我的意思:https://godbolt.org/z/FaEGTV
template <typename T, int... I> struct Vec { };
struct A
{
template<template<typename, int...> typename... Container,
typename... Ts, int... Is>
A(Container<Ts,Is...>... );
};
A a(Vec<int, 0>{}, Vec<double, 0>{}); // ok
A b(Vec<int, 0, 1>{}, Vec<double, 0, 1>{}); // ok
A c(Vec<int, 0>{}, Vec<double, 0, 1>{}); // error
我希望标记为 //error
的行使用与我类似的语法。显然,如果我编写一个特殊的构造函数来处理这种情况,它会工作得很好。不过,我希望它适用于任意数量的容器,而无需我针对所有可能的情况明确说明它。例如,如果我有 2 个容器 a,b
,其索引集 {0,1,2}
和 {0,1,2,3}
扩展应类似于 A(a[0],a[1],a[2], b[0],b[1],b[2],b[3])
.
我知道我可以递归地执行此操作,一次解压一个容器,然后递归地委托(delegate)给构造函数,期望一开始只包含一系列平面元素。我的问题是这是否可以以更优雅、更高效、更简洁的方式实现。
最佳答案
For example, if I have 2 containers
a,b
, with index sets{0,1,2}
and{0,1,2,3}
the expansion should look likeA(a[0],a[1],a[2], b[0],b[1],b[2],b[3])
.I am aware that I could do this recursively, unpacking one container at a time, and delegating recursively to constructors expecting a sequence of only flat elements in the beginning. My question is whether this is feasible in a more elegant, efficient, and less verbose way.
您是否接受这样的解决方案:扩展为您提供带有 a[0],a[1],a[2], b[0],b 的
?std::tuple
[1],b[2],b[3]
在这种情况下,您可以按照 Igor 的建议,将容器中的值解压并将它们重新打包到元组中,然后使用 std::tuple_cat()
连接元组。
我的意思是......给定一个容器/元组转换器,如下
template <template<typename, std::size_t...> typename C,
typename T, std::size_t... Is>
auto getTpl (C<T, Is...> const & v)
{ return std::make_tuple(v.data[Is]...); }
您可以开始编写构造函数,调用委托(delegate)构造函数,如下所示
template <typename ... Ts>
A (Ts const & ... ts) : A{ std::tuple_cat( getTpl(ts)... ) }
{ }
最终的构造函数是
template <typename ... Ts>
A (std::tuple<Ts...> const & tpl)
{ /* do something with values inside tpl */ }
以下是完整的编译示例
#include <iostream>
#include <string>
#include <tuple>
template <typename T, std::size_t ... Is>
struct Vec
{
T data [sizeof...(Is)] = { Is... };
T const & operator[] (std::size_t i) const
{ return data[i]; }
T & operator[] (std::size_t i)
{ return data[i]; }
};
template <template<typename, std::size_t...> typename C,
typename T, std::size_t... Is>
auto getTpl (C<T, Is...> const & v)
{ return std::make_tuple(v.data[Is]...); }
struct A
{
template <typename ... Ts>
A (std::tuple<Ts...> const & tpl)
{ /* do something with values inside tpl */ }
template <typename ... Ts>
A (Ts const & ... ts) : A{ std::tuple_cat( getTpl(ts)... ) }
{ }
};
int main ()
{
A a(Vec<int, 0>{}, Vec<double, 0>{}); // ok
A b(Vec<int, 0, 1>{}, Vec<double, 0, 1>{}); // ok
A c(Vec<int, 0>{}, Vec<double, 0, 1>{}); // ok, now
}
关于c++ - 将非类型参数包分布在不同的模板参数包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58543122/