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

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

本文关键字:参数 返回类型 stl-container 输入 函数      更新时间:2023-10-16

我有一个函数,其目标是获取特定数据类型的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>

虽然这个问题的精神类似于返回转换容器的 std::transform-like 函数,但最流行的解决方案指向我需要特别避免的模板元编程。 使用可变参数模板参数的解决方案解决了这个问题。

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

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

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

这是您的新界面:

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

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

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

现在你可以这样称呼它:

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

现场演示 (C++14(

为什么不直接使用构造函数?

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