8

Here is my example classes :

template<typename T> class MyClassVector
{
    public:
        inline const std::vector<T>& data() const
        {
            return _data;
        }

    protected:
        std::vector<T> _data;
};

template<typename T, unsigned int SIZE> class MyClassArray
{
    public:
        inline const /* SOMETHING */ data() const
        {
            return _data; // OR SOMETHING ELSE
        }

    protected:
        T _data[SIZE];
};

My question is : what is the equivalent of the MyClassVector data() function for the MyClassArray class to return a constant reference to the underlying _data container ?

Thank you very much !

5 Answers 5

16

There are two ways to do this: The direct and the readable:

Direct:

inline T const (& data() const)[SIZE] {
  return _data;
}

Readable:

typedef T Data[Size];
inline Data const& data() const {
  return _data;
}
Sign up to request clarification or add additional context in comments.

Comments

3

The closest syntax would be returning a reference to a an array of const T. The simple way of writting that is by means of typedefs:

template <typename T, unsigned int N>
class MyClassArray {
public:
   typedef T array_t[N];
   typedef const T carray_t[N];
   array_t _data;

   carray_t& data() const {
      return _data;
   }
};

The harder to read way is actually spelling the type in the function declaration:

const T (&foo() const)[N] {
   return _data;
}

2 Comments

Aw, shoot. Now I see your answer. +1, gunslinger.
@bitmask: Neither of us was precisely fast... +1 to your answer (how can I not agree with myself :)
0

You can return a const reference to a SIZE sized array of T. I have no idea what the syntax for this is, but you can use type traits to produce it. But more relevantly, you are simply poorly duplicating std::array<T, N>, which can also be found in Boost/TR1, so it's a tad of a waste of time.

#include <type_traits>

class X {
    int arr[5];
    std::add_reference<std::add_const<int[5]>::type>::type foo() {
        return arr;
    }
};

This will return a size-aware const reference to your array.

5 Comments

The syntax is very ugly: inline const T(&data() const)[SIZE]
That should probably be std::add_lvalue_reference.According to g++4.7 the result will not be what the user wants, but rather int const* --although to be honest I don't quite understand why.
Since the int and the 5 are actually template arguments, you'll need two typenames thrown in there.
Oh, I don't, but the OP would. MSDN doesn't mention a std::add_lvalue_reference.
@DeadMG: I was reading the standard (n3337, first draft after approved standard, only editorial changes) and there are two add reference metafunctions: add_lvalue_reference and add_rvalue_reference (§20.9.2/§20.9.7.2)
0

There's no way to do this typesafely since arrays just decay to a pointer. The equivalent would be returning a const pointer, but then the caller has no way to know the size.

Anyway, there's no reason to use raw arrays anymore. Std::array would solve the problem and be much nicer to work with as well.

Edit, nevermind it is possible to pass references to raw arrays (see above). That doesn't mean you should do it though. std::array is better.

3 Comments

I didn't downvote, but it is possible to return a reference to an array; it won't decay automatically.
I downvoted because you can, in fact, return a type-safe reference. Sorry it took me a few minutes to explain, I was discovering that I had completely forgotten the syntax.
@Dead thanks for the explanation. It's really frustrating to get downvoted and have no idea why, or whether anything I said was wrong. Now I've learned something.
0

Why not just expose the array as pointer to const instance of T? And also the the size of the array?

template<typename T, std::size_t SIZE>
class MyClassArray {
public:
    inline const int* data() const
    {
        return _data;
    }

    inline std::size_t size() const
    {
        return SIZE;
    }

protected:
    std::size_t _data[SIZE];
};

There is an analogous approach: see std::string class, c_str() and size() member functions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.