模板化函数以从输入参数推导出返回类型stl-container

时间:2017-07-25 20:01:21

标签: c++ templates stl containers c++14

我有一个函数,其目标是获取特定数据类型的stl容器并返回不同特定数据类型的相同stl容器。见下文:

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

您可以将其用作:

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

一个(或可以一个)怎么写这个,以便可以从输入容器中推断出返回容器?

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

虽然这个问题的精神类似于The std::transform-like function that returns transformed container,但最流行的解决方案指向模板元编程,我需要特别避免。使用可变参数模板参数的解决方案解决了这个问题。

2 个答案:

答案 0 :(得分:1)

我回答是因为暗示人们在评论中所做的似乎并没有帮助你。

对于与其关联的单一类型的矢量容器(例如,vectorlist,而不是map)(例如vector<int>),您可以接受用于匹配容器的可变参数模板模板参数,但您还必须记住,这些容器的模板定义通常包含除类型之外的其他内容。例如,分配器(很少使用,但允许您对内存分配进行一些控制)。

我们经常忘记Allocator等,因为这些通常是默认的。

这是您的新界面:

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

您明确指出要匹配int的容器并转换为double的容器,所以我在这里复制了它。

Args...将匹配分配器(以及类型后的任何其他模板参数)。我们可以忽略在返回类型中指定Allocator,因为回想一下它以及它之后的其他参数通常是默认的。

现在你可以这样称呼它:

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

答案 1 :(得分:0)

为什么不使用构造函数?

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