C++ 将函数应用于参数包中按错误顺序发生的每个元素

C++ 将函数应用于参数包中按错误顺序发生的每个元素,c++,c++11,tuples,callstack,string-parsing,C++,C++11,Tuples,Callstack,String Parsing,所以我有一个简单的问题,结果比我预期的要困难得多 代码: template <typename R, typename... Args> void ApplyString(R(*func)(Args...), std::string args) { auto argtuple = std::make_tuple(GetToken<Args>(args)...); typename GetIndexTuple<Args...>::type ind

所以我有一个简单的问题,结果比我预期的要困难得多

代码:

template <typename R, typename... Args>
void ApplyString(R(*func)(Args...), std::string args)
{
    auto argtuple = std::make_tuple(GetToken<Args>(args)...);
    typename GetIndexTuple<Args...>::type indices;
    ApplyTuple(func, argtuple, indices);
}
template <typename Head, typename... Tail>
std::tuple<Head, Tail...> StringToTuple(std::tuple<Head, Tail...>, std::string& args)
{
    auto head = std::make_tuple(GetToken<Head>(args));
    return std::tuple_cat(head, StringToTuple(std::tuple<Tail...>(), args));
}
std::tuple<> StringToTuple(std::tuple<>, std::string& args)
{
    return std::tuple<>();
}

template <typename R, typename... Args>
R ApplyString(std::function<R(Args...)> func, std::string args)
{
    std::tuple<Args...> argtuple = StringToTuple(std::tuple<Args...>(), args);
    return ApplyTuple(func, argtuple);
}
然后我这样使用它:

ApplyString(Output, "10 7 5 ");
预期输出为:
10,7,5
。然而,实际输出是:
5,7,10
。我想知道是否有人知道如何帮助我解决这个问题。据我所知,函数调用顺序似乎与参数包扩展顺序相反。我理解正确吗


提前谢谢

所以我想出了一个办法,虽然它不是最漂亮的,但它确实管用。我制作了一个函数来用字符串构建指定类型的元组,然后我用它来代替make_tuple

代码:

template <typename R, typename... Args>
void ApplyString(R(*func)(Args...), std::string args)
{
    auto argtuple = std::make_tuple(GetToken<Args>(args)...);
    typename GetIndexTuple<Args...>::type indices;
    ApplyTuple(func, argtuple, indices);
}
template <typename Head, typename... Tail>
std::tuple<Head, Tail...> StringToTuple(std::tuple<Head, Tail...>, std::string& args)
{
    auto head = std::make_tuple(GetToken<Head>(args));
    return std::tuple_cat(head, StringToTuple(std::tuple<Tail...>(), args));
}
std::tuple<> StringToTuple(std::tuple<>, std::string& args)
{
    return std::tuple<>();
}

template <typename R, typename... Args>
R ApplyString(std::function<R(Args...)> func, std::string args)
{
    std::tuple<Args...> argtuple = StringToTuple(std::tuple<Args...>(), args);
    return ApplyTuple(func, argtuple);
}
模板
std::tuple StringToTuple(std::tuple、std::string和args)
{
autohead=std::make_tuple(GetToken(args));
返回std::tuple_cat(head,StringToTuple(std::tuple(),args));
}
std::tuple StringToTuple(std::tuple、std::string和args)
{
返回std::tuple();
}
模板
R ApplyString(std::function func,std::string args)
{
std::tuple argtuple=StringToTuple(std::tuple(),args);
返回ApplyTuple(func,argtuple);
}

它现在确实有效,但如果有人有更好的解决方案,请发布它。干杯

使用列表初始化,它保证从左到右的求值顺序,而不是按实现定义的顺序求值的函数参数。您的意思是“std::tuple argtuple={GetToken(args)…..};”?因为这给了我一个错误:“错误C2440:‘初始化’:无法从‘初始值设定项列表’转换为‘std::tuple’”。我认为这是行不通的,因为列表无法保存不同类型的数据。是的,没错,列表初始化。只要松开
=
,因为
std::tuple
构造函数是显式的。列表可以包含异构类型,不要被
std::
中的所有同构类型所愚弄。我还尝试使用“std::tuple argtuple{GetToken(args)…};”进行初始化。输出仍然是:5,7,10。当您删除“=”时,它似乎不再是一个“初始值设定项列表”,因此失去了从左到右的实例化。”然后,我使用该函数调用
ApplyTuple
,它会执行它所说的“错误也可能隐藏在那里或索引生成中(
GetIndexTuple
),或者在<代码> GoTebug 中,这取决于你认为“更好”的是什么。您可以将字符串按空格分割,并将标记按相反顺序放回:尽管pMy标记器相当健壮,例如get标记字符串将在引号中获取整个字符串或带有空格delim的单词,以先到者为准。所以那真的不行。