template
函数接受 any std::vector
by的正确方法const&
是:
template<typename T, typename A>
void some_func( std::vector<T,A> const& vec ) {
}
第二个参数是“分配器”,在某些高级用法中std::vector
它不是默认的。如果您只接受std::vector<T>
,您some_func
将拒绝std::vector
s 与替代分配器。
现在,还有其他方法可以解决这个问题,我将快速列出。我将按成本效益比递减的方式列出它们——上面的一个可能是你想要的,下一个有时是有用的,然后我将分支到很少值得考虑的过度设计的案例(但可能有用在某些极端情况下)。
T
您可以通过then 测试来接受任意类型T&&
以确定是否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 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(...)
).
As type erasure of std::vector<T> const&
to a random-access range view of contiguous T
s 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.
c++20 may make this much easier, because the multi-step SFINAE above will collapse into a few requires clauses.