简体   繁体   English

模板化函数以根据输入参数推断出返回类型stl-container

[英]Templating a function to deduce the return type stl-container from input arguments

I have a function where the objective is to take an stl-container of a specific data type and return the same stl-container of a different specific data type. 我有一个函数,目标是获取特定数据类型的stl容器并返回不同特定数据类型的相同stl容器。 See below: 见下文:

template <
template <typename, typename = std::allocator<double> > class ReturnContainer,
template <typename, typename = std::allocator<int> > class Container
    >
inline ReturnContainer<double> transform(const Container<int>& container)
{
  ReturnContainer<double> ret(container.size());

  for(size_t i = 0; i < container.size(); ++i)
  {
    // Do something here
  }
  return ret;
}

Which you could use as: 您可以将其用作:

//
// Using vectors
//
std::vector<int> data_vector_in;
data_vector_in.push_back(0.0);
data_vector_in.push_back(1.0);

std::vector<double> data_vector_out = transform<std::vector>(data_vector_in);

//
// Using lists
//
std::list<int> data_list_in;
data_list_in.push_back(0.0);
data_list_in.push_back(1.0);

std::list<double> data_list_out = transform<std::list>(data_list_in);

How could one (or can one) write this so that the return container can be deduced from the input container? 一个人(或一个人)如何写这个,以便可以从输入容器中推断出返回容器?

std::vector<double> data_vector_out = transform(data_vector_in); // No <std::vector>

Although the spirit of this question is similar to The std::transform-like function that returns transformed container , the most popular solution pointed to template metaprogramming which I need to specifically avoid. 尽管此问题的实质类似于返回转换后的容器的类似于std :: transform的函数 ,但最流行的解决方案是针对模板元编程,我需要特别避免。 The solution for using variadic template parameters solved this issue. 使用可变参数模板参数的解决方案解决了此问题。

I'm answering because it seems that the hinting people are doing in the comments isn't helping you out. 我之所以回答,是因为似乎人们在评论中所做的暗示没有帮助您。

For vector-containers (eg, vector and list , and not map ) that have a single type associated with them (eg vector<int> ), you can accept a variadic template template parameter to match the container, but you must also remember that the template definitions for these containers often contain things other than the type. 对于具有单个类型的矢量容器(例如, vectorlist ,而不是map )(例如, vector<int> ),您可以接受可变参数模板模板参数来匹配容器,但是您还必须记住这些容器的模板定义通常包含类型以外的内容。 For example, an Allocator (which is rarely used, but allows you to have some control over memory allocation). 例如,一个分配器(很少使用,但允许您对内存分配进行一些控制)。

We forget about the Allocator etc. often because these are usually defaulted. 我们经常忘记Allocator等,因为这些通常是默认的。

Here's your new interface: 这是您的新界面:

template <template<class...> class Container, class... Args>
Container<double> transform(const Container<int, Args...>& container);

You were explicit about matching a container of int and transforming to a container of double , so I replicated that here. 您明确地知道要匹配一个int容器并将其转换为double容器,因此我在此处进行了复制。

The Args... will match the Allocator (and any other template arguments after the type). Args...将匹配分配器(以及类型之后的任何其他模板参数)。 We are able to ignore specifying the Allocator in the return type because recall that it, and other arguments after it, are usually defaulted. 我们可以忽略在返回类型中指定Allocator的原因,因为回忆起它和它后面的其他参数通常是默认的。

Now you can call it like so: 现在您可以这样称呼它:

// Using vectors
std::vector<int> data_vector_in{0, 1};
auto data_vector_out = transform(data_vector_in);

// ensure we got the right type back
static_assert(std::is_same<decltype(data_vector_out), std::vector<double>>::value, "Err");

// Using lists
std::list<int> data_list_in{0, 1};
auto data_list_out = transform(data_list_in);
static_assert(std::is_same<decltype(data_list_out), std::list<double>>::value, "Err");

Live Demo (C++14) 现场演示 (C ++ 14)

Why not just using constructors? 为什么不只使用构造函数?

std::vector<int> data_vector_in;
std::vector<double> data_vector_out(data_vector_in.begin(), data_vector_in.end());

std::list<int> data_list_in;
std::list<double> data_list_out(data_list_in.begin(), data_list_in.end());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM