std :: vector作为模板函数参数 [英] std::vector as a template function argument

查看:750
本文介绍了std :: vector作为模板函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个将std :: vector引用作为参数的类方法,并且希望将其用于不同类型的数据。

I want to make a class method that takes a std::vector reference as an argument and I want to use it with different types of data.

该函数应该看起来像:

The function should look like:

void some_function(const std::vector & vect){ //do something with vector }

我想使用它,例如:

std::vector<int> v1;
some_function(v1);
std::vector<string> v2;
some_function(v2);

我希望我的观点清楚。
我必须制作这样的模板方法吗?

I hope that I made my point clear. Do I have to make a template method like that:

template<class T>
void some_function(std::vector<T> & vect){}

或我可以用其他方式吗?

or can I do it in another way? If I have to, please tell me how I can write that method in a class.

感谢您的帮助!

推荐答案

模板函数接受任何 std :: vector const& 的c>是:

The right way for a template function to accept any std::vector by const& is:

template<typename T, typename A>
void some_func( std::vector<T,A> const& vec ) {
}

第二个参数是分配器,在 std :: vector 的某些高级用法中,它将不是默认值。如果您只接受 std :: vector< T> ,则您的 some_func 将拒绝 std: :vector 和其他分配器。

the second argument is the "allocator", and in some advanced usage of std::vector it will not be the default one. If you just accept std::vector<T>, your some_func will reject std::vectors with alternative allocators.

现在,还有其他方法可以快速列出。我将以降低的成本效益比列出它们-上面的一个可能是您想要的,而下一个有时是有用的,然后,我将分为一些很少考虑的过度设计的案例(但可能有用)

Now, there are other ways to approach this that I will list quickly. I will list them in decreasing cost:benefit ratio -- the one above is probably what you want, and the next one is sometimes useful, and after that I will branch off into over engineered cases that are rarely worth considering (but might be useful in some corner cases).

您可以通过 T&接受任意类型的 T 。 & 然后测试以确定 typename std :: remove_reference< T> :: type 是否是 std的一种: :vector 。这将允许您对传入的 std :: vector 进行完美转发。它还可以让您更改用于测试的谓词,以接受不仅仅是 std :: vector :大部分情况下的 const& std :: vector 可能只需要一些任意的随机访问容器。

You could accept an arbitrary type T by T&& then test to determine if typename std::remove_reference<T>::type is a kind of std::vector. This would allow you to do "perfect forwarding" of the incoming std::vector. It would also let you change the predicate you use to test to accept more than just a std::vector: for the most part, const& to std::vector probably just needs some arbitrary random-access container.

A荒唐可笑的方法是做两步功能。第二步是使用SFINAE将固定类型 T 的类型擦除后的随机访问范围视图(或者如果您不需要随机访问,则只是一个范围视图)为了确保传入对象是兼容的,第一步推导传入类型的容器类型,并在SFINAE上下文中调用第二步( auto some_func(...)-> decltype(。 。))。

A ridiculously fancy way would be to do a two-step function. The second step takes a type-erased random-access range view (or just a range-view if you don't need random access) for a fixed type T with SFINAE to ensure that the incoming object is compatible, the first step deduces the container type of the passed in type and calls the second step in a SFINAE context (auto some_func(...)->decltype(...)).

由于类型为 std :: vector< T>的擦除const& 到连续 T s的随机访问范围视图不会损失太多功能,优点是您可以保证函数主体与 std :: vector< T>完全相同const& 并用于 T [n] 并用于 std :: array< T,n>

As type erasure of std::vector<T> const& to a random-access range view of contiguous Ts doesn't lose much functionality, an advantage would be that you could guarantee that the body of your function is exactly the same for std::vector<T> const& and for T[n] and for std::array<T,n>.

这不是很大的优势,尤其是对于所需的样板。

It isn't a big advantage, especially for the boilerplate required.

可能会使此问题容易得多,因为上面的多步骤SFINAE将分解为一些require子句。

c++20 may make this much easier, because the multi-step SFINAE above will collapse into a few requires clauses.

这篇关于std :: vector作为模板函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆