2

Checking if a sequence container is contiguous in memory.
C++ templates that accept only certain types

I am writing a simple send() method, which internally works with C-style pointers. I would like it to be able to work with all the guaranteed sequence containers. My motivation being twofold:

  • a flexible interface
  • efficiency - using std::array avoids heap allocations.

Here is how far I am:

template <typename Container>
void poll( Container &out )
{
    static_assert( std::is_base_of< std::array<typename Container::value_type>, Container >::value  ||
                   std::is_base_of< std::vector<typename Container::value_type>, Container >::value ||
                   std::is_base_of< std::string<typename Container::value_type>, Container >::value,
                   "A contiguous memory container is required.");
}

Trouble is, std::array requires a second parameter, and that cannot be known at compile time. Is this problem solvable? Possibly by a different approach?

Community
  • 1
  • 1
Vorac
  • 8,726
  • 11
  • 58
  • 101

3 Answers3

7

How about if the container has a data() member function? (that returns a pointer)

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
7

The right way here is to use a trait class. std::is_base_of is a kind of trait. Basically: You have a templated struct that takes a (template) param and returns its result via a nested type/value.

In your case something like this

template<typename T>
struct HasContiguousStorage: public std::false_type{};

template<typename T>
struct HasContiguousStorage<std::vector<T>>: public std::true_type{};
// Specialize others

As you should not derive from standard containers, this should be enough. This can also check for the array:

template<typename T, size_t N>
struct HasContiguousStorage<std::array<T,N>>: public std::true_type{};

In your function you can then either overload it (see enable_if) or branch on it (branch will be evaluated at compile-time)

Flamefire
  • 5,313
  • 3
  • 35
  • 70
0

While you cannot do it yet, I am in the process of updating n4183 Contiguous Iterators: Pointer Conversion & Type Trait for (hopeful) inclusion in a future C++ standard.

Nevin
  • 4,595
  • 18
  • 24