gpt4 book ai didi

c++ - 如何推断迭代器模板类型或其模板的嵌套类型?

转载 作者:太空宇宙 更新时间:2023-11-04 14:15:04 26 4
gpt4 key购买 nike

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

假设我声明了以下类型

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

它会像这样用工厂函数构造

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));

构造函数将类似如下

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;
}

我知道我可以更改函数以返回一些容器(或者甚至模板化容器类型),例如

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 的方法?看起来对来电者来说是最灵活的?
  2. 如何在 build_instances 主体中获取 numeric_type(就像通过 output_iterator 获取它一样)以便它可以用于逐个构建实例一个?
  3. 如何确保调用者知道等待包装在 std::unique_ptr 中的对象?另一种选择就是简单的指针,但我对此并不热心。

有一个标题为 How can I make this template method more elegant? (or: less explicit template parameters required) 的类似问题,它接受一个容器并将其转换为不同类型的容器。

编辑正如对 Jogojapan 的评论所说,目前我像这样转换输入

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

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

最佳答案

侵入式解决方案是让some_type以同样的方式公开其类型参数 std::unique_ptr<T, D>通过 element_type 公开其第一个参数(我们稍后需要):

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>);
}

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

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 的特化。)这也可以避免您的问题。

关于c++ - 如何推断迭代器模板类型或其模板的嵌套类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11967193/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com