如何推断迭代器模板类型,或其模板的嵌套类型? [英] How to deduce iterator template type, or its template's nested type?

查看:203
本文介绍了如何推断迭代器模板类型,或其模板的嵌套类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题需要更多的准备,所以我先提供一些位的代码然后确切的问题

This questions begs a more preparation, so I provide some bits of code first and then the exact question

假设我有以下类型声明

template<typename T>
struct some_type
{
    T t_;
};

这将使用像这样的工厂函数构建

which would be constructed with a factory function like so

typedef float numeric_type;
std::vector<std::string> construction_material;
//Push_back of strings in certain form...
std::vector<std::unique_ptr<some_type<numeric_type>> instances;
build_instances(construction_material.begin(), construction_material.end(), back_inserter(instances));

,构造函数将是之后的

and the construction function would be something like following

template<typename input_iterator, typename output_iterator>
output_iterator build_instances(input_iterator begin, input_iterator end, output_iterator out)
{
    for(input_iterator iter = begin; iter != end; ++iter)
    {
        //This won't work, but to illustrate some ideas...
        //build_instance<std::iterator_traits<output_iterator>::value_type>(*iter)
    }

    //[...]

    return *out;
}

template<typename T>
std::unique_ptr<some_type<T>> build_instance(std::string const& material)
{
    static_assert(std::is_floating_point<T>::value == true, "The template type needs to be a floating point type.");

    std::unique_ptr<some_instance<T>> instance(new some_instance<T>());
    //Some processing...

    return instance;
}



我知道我可以改变函数返回一些容器容器类型),如

I know I could change the function to return some container (or perhaps even templatize the container type), like

template<typename input_iterator, typename T>
std::vector<std::unique_type<T>> build_instances(input_iterator begin, input_iterator end,       
output_iterator out)
{
    //Likewise code to the previous snippets...
    return ...
}

我无法解决的问题是:


  1. 是否可能 - 或不可能 - 使用* back_inserter * like方法?

  2. 如何获得* build_instances * body中* numeric_type *的保持值(如通过output_iterator使用),以便它可以是用于逐个构建实例?

  3. 如何确保调用者知道等待包装在std :: unique_ptrs中的对象?一个替代方案将只是一个简单的指针,但我不是enthuasiastic这一点。

有一个类似的问题与标题如何制作这个模板方法更优雅吗? (或:需要更少的显式模板参数),它接受一个容器并将其转换为不同类型的容器。

There's a similar kind of question with a heading How can I make this template method more elegant? (or: less explicit template parameters required), which takes a container and transforms it to a different type of a container.

strong>
正如Jogojapan的评论,当前我转换输入像这样

Edit As commented to Jogojapan's comment that currently I transform the input like so

std::transform(construction_material.begin(), construction_material.end(), std::inserter(instances, instances.begin()), build_instance<numeric_type>);

但是后续的函数调用需要提供 numeric_type typedef,这是有点麻烦。我希望避免这种情况。它看起来我是错误的,但是为了教育和所有的目的,是否有可能进一步减少typedef数值类型的需要,并从迭代器中推导出来?

but the subsequent function calls need to be supplied the numeric_type typedef too, which is somewhat cumbersome. I hope to avoid that. It looks I was mistaken, but for the purpose of education and all, would it be possible to further reduce the need to typedef the numeric type and deduce it from the iterator?

推荐答案

一个侵入性的解决方案是让 some_type 暴露其类型参数, code> std :: unique_ptr< T,D> 通过 element_type 暴露其第一个参数: p>

An intrusive solution is to let some_type exposes its type parameter, the same way std::unique_ptr<T, D> exposes its first parameter via element_type (which we will need later):

template<typename T>
struct some_type
{
    // give it an appropriate meaningful name
    using value_type = T;
    value_type t_;
};

template<typename input_iterator, typename output_iterator>
output_iterator build_instances(input_iterator begin, input_iterator end, output_iterator out)
{
    using pointer_type = typename std::iterator_traits<output_iterator>::value_type;
    using value_type = typename pointer_type::element_type::value_type;
    return std::transform(begin, end, out, build_instance<value_type>);
}

您还可以非侵入性地提取模板专业化的第一个模板参数:

You can also non-intrusively extract the first template parameter of a template specialization:

template<typename T>
struct first;

template<template<typename...> class Template, typename First, typename... Pack>
struct first<Template<First, Pack...>>> {
    using type = First;
};

template<typename T>
using First = typename first<T>::type;

value_type 别名 build_instances 会改为

using value_type = First<typename pointer_type::element_type>;

作为最后一句话我发现有点奇怪, build_instance 获取 T 参数,但构造 some_type< T> 的实例。如果 T 并且构造了 T 的实例(其中可能 T 限制为 some_type 的专业化。)这也会避免你的问题。

As a final remark I find it a bit odd that build_instance take a T parameter but constructs instances of some_type<T>. If it took T and constructed instances of T (where perhaps T is restricted to be a specialization of some_type.) This would have spared your problem, too.

这篇关于如何推断迭代器模板类型,或其模板的嵌套类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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