std::vector as a template function argument

后端 未结 1 1426
半阙折子戏
半阙折子戏 2020-12-13 19:13

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:

相关标签:
1条回答
  • 2020-12-13 19:54

    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 ) {
    }
    

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

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

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

    0 讨论(0)
提交回复
热议问题