如何转发元组的类型以专门化其他模板? [英] how to forward the types of tuple to specialize other template?

查看:145
本文介绍了如何转发元组的类型以专门化其他模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在研究一种动态容器结构,该结构表示一个容器值或具有具有相同容器类型的指针向量.该容器具有接口optional<T> expect_value<T>().对于pod类型,实现很简单.对于非pod值,我将调用expect_value<tuple<args...>>(),而args也将是元组.但是当实现此功能时,我遇到了一个麻烦:如何将a.expect_value<tuple<args...>>()重定向到a.expect_value_tuple<args...>>().例如,对a.expect_value<tuple<int,int>()的调用将返回a.expect_value_tuple<int, int>()的结果.由于参数为空,因此无法使用解压缩参数的类型推断.然后整个项目再也无法进行了.有任何想法吗?以下是我意图的最小示例.

currently I'm working on a dynamic container structure, which represents one pod value or has vector of pointers with same container type. The container has an interface optional<T> expect_value<T>() 。 For pod types the implemention is simple. For the non pod value, I would call expect_value<tuple<args...>>(), the args would be tuple as well. But when implement this function, I come across a trouble: how to redirect a.expect_value<tuple<args...>>() to a.expect_value_tuple<args...>>(). For example, the call to a.expect_value<tuple<int,int>() would return the result of a.expect_value_tuple<int, int>(). Because the argument is empty, I cant use the type deduce of unpacked arguments. Then the whole project just cant progress any more. Any ideas? Below is the minimal example for my intention.

#include <tuple>
#include <vector>
#include <optional>
#include <functional>

using namespace std;

template<typename T>
struct is_tuple_impl : std::false_type {};

template<typename... Ts>
struct is_tuple_impl<std::tuple<Ts...>> : std::true_type {};

template<typename T>
struct is_tuple : is_tuple_impl<std::decay_t<T>> {};

class my_container;

template<typename... args, size_t... arg_idx>
optional<tuple<args>...> get_tuple_value_from_vector(const vector<my_container*>& v_list, std::index_sequence<arg_idx...>)
{
    auto temp_result = make_tuple((*v_list[arg_idx]).expect_value<arg>()...);

    if(!(get<arg_idx>(temp_result) &&...))
    {
        return nullopt;
    }
    return make_tuple(get<arg_idx>(temp_result).value()...);

}

class my_container
{
public:
    int value_type; // 1 for v_int 2 for v_list 0 empty
    union
    {
        int v_int;
    };
    vector<my_container*> v_list;
    template<typename T> 
    optional<T> expect_simple_value();
    template<typename... args>
    optional<tuple<args...>> expect_tuple_value();
    template<typename T> 
    optional<T> expect_value();
};
template <typename T>
optional<T> my_container::expect_simple_value()
{
    return nullopt;
}

template <>
optional<int> my_container::expect_simple_value()
{
    if(value_type == 1)
    {
        return v_int;
    }
    return nullopt;
}

template<typename... args>
optional<tuple<args...>> my_container::expect_tuple_value()
{
    if(v_list.size() == 0)
    {
        return nullopt;
    }
    for(const auto i: v_list)
    {
        if(!i)
        {
            return nullopt;
        }
    }
    auto the_tuple_size = sizeof...(args);
    if(v_list.size() != the_tuple_size)
    {
        return nullopt;
    }
    return get_tuple_value_from_vector<args...>(v_list, index_sequence_for<args...>{});
}
template <typename T>
optional<T> my_container::expect_value()
{
    if(is_tuple<T>::value)
    {
        return expect_tuple_value<T>();
    }
    else
    {
        return expect_simple_value<T>();
    }
}

int main()
{
    my_container test_value;
    test_value.value_type = 1;
    test_value.v_int = 1;
    auto result = test_value.expect_value<tuple<int, int>>();
    if(result)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

问题的核心是return expect_tuple_value<T>();行,当逻辑到达那里时,T应该是tuple<args...>,但是我要返回的是return expect_tuple_value<args...>().

the heart of the problem is the line return expect_tuple_value<T>(); When logic goes there, the T should be tuple<args...>, but what I want is return return expect_tuple_value<args...>().

推荐答案

如何通过对函数模板进行部分排序来使用模板参数推导和重载解析:

What about using template argument deduction and overload resolution through partial ordering of function template:

class my_container
{

public:
    template<class T> optional<T> expect_value_simple();

    template<class...Args> optional<tuple<Args...>> expect_value_tuple();


private:
    template<class T> struct deduce_type{};

    template<typename T> 
    auto expect_value_dispatching(deduce_type<T>){
       return expect_value_simple<T>();
       }
    template<typename...Args>
    auto expect_value_dispatching(deduce_type<tuple<Args...>>){
       return expect_value_tuple<Args...>();
       }
public:     
    template<typename T> 
    auto expect_value(){
        return expect_value_dispatching(deduce_type<T>{});
        }
};

(演示)

这篇关于如何转发元组的类型以专门化其他模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆