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

时间:2022-01-28 16:00:47

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!

感谢帮助!

1 个解决方案

#1


26  

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

模板函数通过const&接受任何std :: vector的正确方法是:

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

第二个参数是“allocator”,在std :: vector的一些高级用法中,它不是默认值。如果你只接受std :: vector ,你的some_func将拒绝带有替代分配器的std :: vectors。

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

您可以通过T &&接受任意类型T然后测试以确定typename std :: remove_reference :: type是否是一种std :: vector。这将允许您对传入的std :: vector进行“完美转发”。它还可以让你改变你用来测试的谓词来接受不仅仅是一个std :: vector:在大多数情况下,const和to 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 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(...)).

一种荒谬的幻想方式是做两步功能。对于具有SFINAE的固定类型T,第二步采用类型擦除的随机访问范围视图(或者只是范围视图,如果您不需要随机访问)以确保传入对象兼容,第一步推断传入类型的容器类型,并在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 const的类型擦除和连续Ts的随机访问范围视图不会失去太多功能,因此可以保证函数体对于std完全相同: :vector const&和T [n]以及std :: array ,n>

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

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

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

c ++ 20可以使这更容易,因为上面的多步SFINAE将崩溃成几个require子句。

#1


26  

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

模板函数通过const&接受任何std :: vector的正确方法是:

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

第二个参数是“allocator”,在std :: vector的一些高级用法中,它不是默认值。如果你只接受std :: vector ,你的some_func将拒绝带有替代分配器的std :: vectors。

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

您可以通过T &&接受任意类型T然后测试以确定typename std :: remove_reference :: type是否是一种std :: vector。这将允许您对传入的std :: vector进行“完美转发”。它还可以让你改变你用来测试的谓词来接受不仅仅是一个std :: vector:在大多数情况下,const和to 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 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(...)).

一种荒谬的幻想方式是做两步功能。对于具有SFINAE的固定类型T,第二步采用类型擦除的随机访问范围视图(或者只是范围视图,如果您不需要随机访问)以确保传入对象兼容,第一步推断传入类型的容器类型,并在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 const的类型擦除和连续Ts的随机访问范围视图不会失去太多功能,因此可以保证函数体对于std完全相同: :vector const&和T [n]以及std :: array ,n>

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

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

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

c ++ 20可以使这更容易,因为上面的多步SFINAE将崩溃成几个require子句。