C++ std::vector 作为模板函数参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19094340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:30:16  来源:igfitidea点击:

std::vector as a template function argument

c++templatesstdvector

提问by Prettygeek

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.

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

The function should look like:

该函数应如下所示:

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

and I want use it with for example:

我想将它用于例如:

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.

或者我可以用另一种方式来做吗?如果必须,请告诉我如何在类中编写该方法。

Thanks for help!

感谢帮助!

回答by Yakk - Adam Nevraumont

The right way for a templatefunction to accept any std::vectorby const&is:

template函数接受 any std::vectorby的正确方法const&是:

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

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

第二个参数是“分配器”,在一些高级用法中std::vector它不会是默认的。如果您只是 accept std::vector<T>,您some_funcstd::vector使用替代分配器拒绝s 。

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

现在,还有其他方法可以解决这个问题,我将快速列出。我将按照降低的成本:收益比率列出它们——上面的可能是你想要的,下一个有时有用,之后我将分支到很少值得考虑的过度设计的案例(但可能有用)在某些极端情况下)。

You could accept an arbitrary type Tby T&&then test to determine if typename std::remove_reference<T>::typeis 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::vectorprobably just needs some arbitrary random-access container.

您可以接受任意类型TT&&然后测试以确定是否typename std::remove_reference<T>::type是一种std::vector. 这将允许您对传入的std::vector. 这也将让你改变你用它来测试接受不仅仅是一个断言std::vector:在大多数情况下,const&std::vector可能只是需要一些任意的随机访问容器。

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 Twith 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(...)).

一个可笑的奇特方法是执行两步函数。第二步T使用SFINAE对固定类型进行类型擦除的随机访问范围视图(如果不需要随机访问,则仅使用范围视图)以确保传入的对象兼容,第一步推导出容器传入类型的类型,并在 SFINAE 上下文 ( auto some_func(...)->decltype(...)) 中调用第二步。

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>.

由于std::vector<T> const&对连续Ts的随机访问范围视图的类型擦除不会失去太多功能,因此一个优点是您可以保证您的函数体对于std::vector<T> const&和 forT[n]和 for完全相同std::array<T,n>

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

这不是一个很大的优势,特别是对于所需的样板。

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

c++20可能会使这变得更容易,因为上面的多步骤 SFINAE 将折叠成几个需要子句。