我有一个函数,其目标是获取特定数据类型的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,但最流行的解决方案指向模板元编程,我需要特别避免。使用可变参数模板参数的解决方案解决了这个问题。
答案 0 :(得分:1)
我回答是因为暗示人们在评论中所做的似乎并没有帮助你。
对于与其关联的单一类型的矢量容器(例如,vector
和list
,而不是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");
答案 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());