错误:未定义模板 'std::tuple_element<0, std::tuple<std::string, int> &>'

问题描述 投票:0回答:1

我已经查看了与此错误相关的帖子,但无法使用这些解决方案来解决我的问题。所以我有这段代码尝试通过将字符串化值转换为数组中相应的类型来动态创建一个元组,因为我有一个通用函数,旨在生成该值并将其添加到元组中,但它似乎抛出错误每当我尝试通用设置其返回类型时。

这是将字符串化参数转换为其实际类型的通用函数 (它只是一个最小的例子,顺便说一句,不是我在代码库中编写的整个函数)。

#include <string>
#include <iostream>
#include <tuple>
#include <vector>
#include <type_traits>

template <typename T>
T convertArg(string type, string arg)
{   
    if (type == "Integer") {
        int temp = stoi(arg);
        return temp;
    } else if (type == "Boolean") {
        return arg == "true" ? true : false;
    } else {
        return arg;
    }
};

我有一个运行时循环,可以使用上面的函数创建元组。

namespace detail
{
    template <int... Is>
    struct seq
    {
    };

    template <int N, int... Is>
    struct gen_seq : gen_seq<N - 1, N - 1, Is...>
    {
    };

    template <int... Is>
    struct gen_seq<0, Is...> : seq<Is...>
    {
    };
    template <typename... Ts, int... Is>
    tuple<Ts...> for_each(tuple<Ts...> &t, std::vector<string> types, std::vector<string> args, seq<Is...>)
    {
// this line throws the error where i try set the return type of the function on the basis of the element at that index in the tuple.
        return make_tuple(convertArg<tuple_element<Is, decltype(t)>::type>(types.at(Is), args.at(Is))...);
    }
}

template <typename... Ts>
tuple<Ts...> for_each_in_tuple(std::tuple<Ts...> &t, std::vector<string> types, std::vector<string> args)
{
    return detail::for_each(t, types, args, detail::gen_seq<sizeof...(Ts)>());
}


int main()
{
    std::vector<std::string> types = {"String", "Integer"};
    std::vector<std::string> args = {"rehan", "12"};
    std::tuple<std::string, int> t;
    t = for_each_in_tuple(t, types, args);
    cout << "Tuple values" << endl;
    cout << get<0>(t) << endl;
    cout << get<1>(t) << endl;
}

完整的错误:

main.cpp:41:38: error: implicit instantiation of undefined template 'std::tuple_element<0, std::tuple<std::string, int> &>'
        return make_tuple(convertArg<tuple_element<Is, decltype(t)>::type>(types.at(Is), args.at(Is))...);

我已经看过其他解决方案,但它对我不起作用,这就是为什么我问这个问题是为了获得与我的特定场景相关的解决方案,顺便说一句,我在 c++ 14 上

c++ c++14
1个回答
0
投票

而不是

decltype(t)
应该是
std::remove_reference_t<decltype(t)>
但这只会导致下一个问题,你的
convertArg
功能将无法工作。所有分支都必须有效,例如,如果
T
std::string
,则返回
int
无效。

我建议您将

vector
types 一起删除,只使用
tuple
中的信息:

template <class T> // primary
T convertArg(const std::string& arg) {
    return arg;
}
template <>
int convertArg<int>(const std::string& arg) {
    return stoi(arg);
}
template <>
bool convertArg<bool>(const std::string& arg) {
    return arg == "true";
}

namespace detail {
template <typename... Ts, std::size_t... Is>
std::tuple<Ts...> for_each(std::tuple<Ts...>& t, const std::vector<std::string>& args,
                      std::index_sequence<Is...>) {
    return make_tuple(
        convertArg<std::tuple_element_t<Is, std::remove_reference_t<decltype(t)> >>(
            args.at(Is))...);
}
}  // namespace detail

template <typename... Ts>
std::tuple<Ts...> for_each_in_tuple(std::tuple<Ts...>& t,
                               const std::vector<std::string>& args) {
    return detail::for_each(t, args, std::index_sequence_for<Ts...>());
}

std::remove_reference_t<decltype(t)>
也可以替换为
std::tuple<Ts...>

© www.soinside.com 2019 - 2024. All rights reserved.