将std::vector扩展到参数包中



我有具有以下签名的方法:

void DoStuff(int i);
void DoStuff(int i, k);
void DoStuff(int i, int k, int l);

我有一个方法,我想从中调用DoStuff方法,如下所示:

void CallDoStuff(const std::vector<int>& vElements) {
// What magic is supposed to happen here to make vElements an expandable pack?
DoStuff(vElemets...);
}

有机会做到这一点吗?使用std::index_sequence的方式正确吗?如果是的话,你能给我一个简单的例子吗?如何将其应用于我的问题?

问题是,从std::vector,您不能--编译时间--提取size()值。

因此,只有将要从向量中使用的元素数作为编译时的已知值传递给CallDoStuff(),才能获得所需的内容。

例如,您可以将其作为模板值传递。

使用helper函数,您可以编写如下

template <std::size_t ... Is>
void CallDoStuff (std::vector<int> const & vElements,
std::index_sequence<Is...> const &)
{ DoStuff(vElements[Is]...); }
template <std::size_t N>
void CallDoStuff (std::vector<int> const & vElements)
{ CallDoStuff(vElements, std::make_index_sequence<N>{}); }

这个电话可能是

CallDoStuff<5u>(v);

如果你可以使用std::array,而不是std::vector,答案是不同的:你可以从类型本身提取size(),所以

template <std::size_t N, std::size_t ... Is>
void CallDoStuff (std::array<int, N> const & vElements,
std::index_sequence<Is...> const &)
{ DoStuff(vElements[Is]...); }
template <std::size_t N>
void CallDoStuff (std::array<int, N> const & vElements)
{ CallDoStuff(vElements, std::make_index_sequence<N>{}); }

它是可调用的,而无需如下解释CCD_

std::array<int, 5u>  arr { 2, 3, 5, 7, 11 };
CallDoStuff(arr); // no more <5u>

结束语:注意std::make_index_sequencestd::index_sequence只能从C++14开始使用。在C++11中,您必须以某种方式替换它们。

只要提供参数数量的上限,这是可能的。

利用Xeo在C++11:上实现std::index_sequence

template <unsigned... Idx>
void trampoline(const std::vector<int>& vElements, seq<Idx...>) {
return DoStuff(vElements[Idx]...);
}
template <std::size_t Arity>
void trampoline(const std::vector<int>& vElements) {
return trampoline(vElements, typename gen_seq<Arity>::seq{});
}
template <unsigned... Idx>
void CallDoStuff(const std::vector<int>& vElements, seq<Idx...>) {
using trampoline_t = void (*)(const std::vector<int>&);
constexpr trampoline_t trampolines[]{
trampoline<Idx>...
};
trampolines[vElements.size()](vElements);
}
template <std::size_t Max>
void CallDoStuff(const std::vector<int>& vElements) {
assert(vElements.size() <= Max);
return CallDoStuff(vElements, typename gen_seq<Max + 1>::seq{});
}

在Wandbox 上实时观看

这是不可能的,模板方法调用在编译时绑定,但std::vector直到运行时才知道它包含多少项,因此无法混合这两个概念。

DoStuff(vElemets...);

在这里,编译器应该根据vElements有多少元素来选择正确的实现。您可以看到这种想法的缺陷,因为std::vector只是一个在调用时可以包含任意数量项的对象。

相关内容

  • 没有找到相关文章

最新更新