I found that I need to identify the types that perform this function many times. I don’t know whether it is elegant to invent such a special “concept” (imagine that it is a concept that includes memory, which is not very abstract), but I agree that something like this will be useful.
Meanwhile, to be practical and translate this concept / requirement into a pure syntactic requirement, let me go back. If we restrict ourselves to the standard, then what are the classes that guarantee (or almost guarantee) contact? in order of relevance:
std::vector<T> T[N]
Of all this, std::vector , std::array , std::string have a member function called .data() . So, if that's enough for you, you can rely on the presence of the .data() -> T* member to indicate continuous memory.
You have two options:
1) Try using the .data() member function to raise a syntax error if the type is not in contact. (It’s not difficult if you replace, for example, t[0] with *t.data() )
2) Use some kind of SFINAE on .data() .
template<class ContiguousSequence, typename = decltype(std::declval<ContigiousSequence>().data())> void fun(ContiguousSequence&& s){...}
In addition, C ++ 17 has std::data , which generalizes it to all types with .data() and additionally overloads for T[N] and std::initializer_list<T> . So you can replace ....data() with std::data(...) above.
The conclusion, I think, is a good convention that if the type has a data function (or .data() in C ++ 11) that returns a pointer to the value type, then the elements are contiguous.
(OK, what about std::valarray<T> ?) This does not work unless you overload std::data(std::valarray<T>&) . But who uses std::valarray , in any case, this is a pretty abandoned C ++ corner, I think)
Finally, note, for example, that std::map and less obviously std::deque do not have a .data() (or std::data(...) ) function. boost::multi_array<..., N> has a .data() member and returns a pointer to an array element, it is not clear whether this is an adjacent sequence in the sense you want (because the order is not obvious), but in some sense this is also contiguous memory allocation.
EDIT: There are currently two suggestions for solving this problem (but at the iterator level) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3884.pdf http: // www .open-std.org / jtc1 / sc22 / wg21 / docs / papers / 2014 / n4284.html