我目前正在尝试实现一个函数,它接受一些data
和一个参数包...args
。我在内部调用了另一个函数,它递归地迭代给定的参数。
遗憾的是我在编译它时遇到了一些问题。显然,编译器一直在尝试编译递归函数,而不是停止递归的重载。
有人知道问题出在哪里吗?
class Sample
{
public:
template<class ...TArgs, std::size_t TotalSize = sizeof...(TArgs)>
static bool ParseCompositeFieldsXXX(const std::vector<std::string> &data, TArgs &&...args)
{
auto field = std::get<0>(std::forward_as_tuple(std::forward<TArgs>(args)...));
//bool ok = ParseField(field, 0, data);
auto x = data[0];
bool ok = true;
if (TotalSize > 1)
return ok && ParseCompositeFields<1>(data, std::forward<TArgs>(args)...);
return ok;
}
private:
template<std::size_t Index, class ...TArgs, std::size_t TotalSize = sizeof...(TArgs)>
static bool ParseCompositeFields(const std::vector<std::string> &data, TArgs &&...args)
{
auto field = std::get<Index>(std::forward_as_tuple(std::forward<TArgs>(args)...));
//bool ok = ParseField(field, Index, data);
auto x = data[Index];
bool ok = true;
if (Index < TotalSize)
return ok && ParseCompositeFields<Index + 1>(data, std::forward<TArgs>(args)...);
return ok;
}
template<std::size_t Index>
static bool ParseCompositeFields(const std::vector<std::string> &data)
{
volatile int a = 1 * 2 + 3;
}
};
int wmain(int, wchar_t**)
{
short x1 = 0;
std::string x2;
long long x3 = 0;
Sample::ParseCompositeFieldsXXX({ "1", "Sxx", "-5,32" }, x1, x2, x3);
return 0;
}
\utility(446): error C2338: tuple index out of bounds
...
\main.cpp(56): note: see reference to class template instantiation 'std::tuple_element<3,std::tuple>' being compiled
最佳答案
替代方法
您似乎在这里使用了相当古老的技术。 Simple expansion是您要搜索的内容:
#include <cstddef>
#include <utility>
#include <tuple>
#include <vector>
#include <string>
class Sample
{
template <std::size_t index, typename T>
static bool parse_field(T&& field, const std::vector<std::string>& data)
{
return true;
}
template <typename Tuple, std::size_t ... sequence>
static bool parse_impl(Tuple&& tup, const std::vector<std::string>& data, std::index_sequence<sequence...>)
{
using expander = bool[];
expander expansion{parse_field<sequence>(std::get<sequence>(tup), data)...};
bool result = true;
for (auto iter = std::begin(expansion); iter != std::end(expansion); ++iter)
{
result = result && *iter;
}
return result;
}
public:
template<class ...TArgs, std::size_t TotalSize = sizeof...(TArgs)>
static bool ParseCompositeFieldsXXX(const std::vector<std::string> &data, TArgs &&...args)
{
return parse_impl(std::forward_as_tuple(std::forward<TArgs>(args)...),
data, std::make_index_sequence<sizeof...(TArgs)>{});
}
};
int main()
{
short x1 = 0;
std::string x2;
long long x3 = 0;
Sample::ParseCompositeFieldsXXX({ "1", "Sxx", "-5,32" }, x1, x2, x3);
return 0;
}
如果您正在查看类似数组的内容,那么它就是数组。除非需要,否则不要使用递归,因为它通常会使事情变得复杂。当然也有异常(exception)。
让它变得更好
如您所见,这里甚至不需要上课。只需将其删除即可。
可能遇到的问题
如果调用顺序很重要,可能会出现一个问题。 IIRC,在 C++17 之前,它没有很强的求值顺序,所以有时你可能会失败。
关于c++ - 参数包的递归迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47790737/