3

I have some legacy C code which I've wrapped with a C++ interface for new C++ code to use. The C code used void* to load data from a file. It knew how much data to load internally based on the enum tag you'd send in:

bool load_data( TAG_TYPE tag, void* data );

My C++ wrapper looks something like:

template<typename T>
T load( TAG_TYPE tag ) {
    T data;
    bool success = load_data( tag, &data );
    assert( success );
    return data;
}

This adds some type safety and is cleaner for C++ code. And we can use auto & const:

const auto foo = load<int>( TAG_NUM_POINTS );

Now someone needs to load an array from the file. They'd like to use std::array because this is C++.

const auto foo = load<std::array<int, 3>>( TAG_RGB_VALUE );

Is this safe? It seems to compile and run fine. Under the covers it will pass &std::array<int, 3> as the data value, instead of the preferred data.data().

It seems like this is an area where I'd want to do template specialization, but then I'd need to add template parameters for the type and size of the std::array? Is that possible, and is it the way to go?

Justin
  • 24,288
  • 12
  • 92
  • 142
Brad
  • 5,492
  • 23
  • 34
  • 1
    This is a should work, but isn't guaranteed by the standard. Nothing prevents the implementer of `std::array` from adding an extra book-keeping variable or two, but I'd like to see what sort of problem they thought they were solving by doing it. Rethink: Wording may have been tightened up after C++14. I don't claim to know C++17 well. – user4581301 Sep 11 '18 at 22:12
  • 2
    @user4581301 I don't know that they are allowed to add an extra book-keeping variable or two. From [cppreference](https://en.cppreference.com/w/cpp/container/array): "This container is an aggregate type with the same semantics as a struct holding a C-style array `T[N]` as its only non-static data member." And the constructor is "implicitly declared" and "following the rules of aggregate initialization" – Justin Sep 11 '18 at 22:15
  • 1
    Possible duplicate of [Why function template cannot be partially specialized?](https://stackoverflow.com/questions/5101516/why-function-template-cannot-be-partially-specialized) – Nir Friedman Sep 11 '18 at 22:17
  • 2
    @NirFriedman Definitely not a duplicate. This question is not about function template specialization although it does present it as a possible solution – Justin Sep 11 '18 at 22:19
  • @Justin best proof of no extra special I can find in the older standards is `std::array` being an aggregate. You'd have a hard time with `std::array x = {1,2};` if there were extra member variables thrown in for smurfs and giggles, but I can't find anything explicitly forbidding it. I can't think of a non-insane reason why anyone would implement `array` with extra cruft and would be absolutely gobsmacked if what the asker has in mind wouldn't work. Too much other stuff would break, like contiguous data in an `array` of `array`. – user4581301 Sep 11 '18 at 22:28
  • 1
    And I retract. Since the first member of `std::array` must be the array, it won't matter a bit to the asker what some fool adds in after the array. – user4581301 Sep 11 '18 at 22:33
  • If `std::array` is not *StandardLayout* (`std::is_standard_layout_v>` is false), I think the chances of this being valid are much lower. – Justin Sep 11 '18 at 22:37
  • @Justin it's not really presented as a possible solution because the question asker doesn't know how to do the specialization either. And FYI it is not guaranteed to be standard layout, AFAIK it can theoretically have anything after the array member. – Nir Friedman Sep 11 '18 at 22:47
  • According to [cppreference](https://en.cppreference.com/w/cpp/container/array): This container is an aggregate type with the same semantics as a struct holding a C-style array T[N] as **its only non-static data member**. – Matt Eding Jun 09 '21 at 23:42

1 Answers1

1

There exists a method in std::array<> called data(). It allows you to access the internal data without having to worry about the implementation. You can read more about it here https://en.cppreference.com/w/cpp/container/array/data

An Example

bool load_data( TAG_TYPE tag, void* data );

template<typename T>
std::array<T> load( TAG_TYPE tag ) {
    std::array<T> data;
    bool success = load_data( tag, data.data() );
    assert( success );
    return data;
}
Aryan
  • 608
  • 6
  • 15