4

I find it rather convenient to have a class which basically acts like std::array but is indexed by values of some enum. I guess it's not very hard to imagine how to implement it, let's say it has a signature like this:

class enum_array <typename EnumT, typename ValueT, size_t N>

On the other hand while trying to implement all of the standard std::array concerned functions I've noticed that writing overloaded std::get function for such class template is not that easy.

First of all, I think that it's only natural for this std::get to have value of aforementioned enum as a template argument and because of it the most of the problems emerge:

1) If I want to define such function outside the class I have to do something like:

namespace std {
template <EnumT Index, typename EnumT, typename ValueT, size_t N>
EnumT &get (enum_array<EnumT, ValueT, N> &val)  

But then the problem arouses that EnumT is still unknown while specifying the first template argument so this template is actually ill formed

If I put EnumT Index on the second or further place of argument list, then there's problem that I cannot really specify only this argument and will have to specify something else along with it and that will not look like normal std::get call on std::array.

2) If I define get function inside enum_array class as a friend function everything will be seemingly fine except the fact that then it'll be placed in the same namespace the class enum_array belongs to. And putting it in namespace std is not the best design.

So my question is: Can std::get with enum arguments be overloaded in a way that I mentioned for such class using C++ template mechanism?

(Want to point out that this question aroused mostly out of curiousity, afterall std::get is not the most useful function for std::array in my opinion)

1
  • 1
    I think you suffer from the (rather) common problem that there's no such thing as template<auto Value> (a template non-type parameter whose type is deduced). So, you either have to specify one function (template) per enum type, à la template<first_enum Value> auto get(..);, template<second_enum Value> auto get(..); etc., or you have to (manually) pass the type of the enum value for each invocation, à la get<first_enum, Value0>(..);, get<second_enum, Value0>(..); Commented Sep 2, 2014 at 16:32

1 Answer 1

5

You can't yet. What you want is Implicit Template Parameters. The committee liked the idea but wanted to see a comparison of the proposed notation with the auto notation mentioned by dyp. I've promised a new draft for November's standards meeting. OK for me to include your example?

Sign up to request clarification or add additional context in comments.

2 Comments

It sure is OK. Though there was an answer here that technically it's not legal to overload functions from std, so maybe it needs some reformulation to adhere to the standard precisely.
Understood, but that doesn't seem like much of an obstacle. You could use using statements to ensure that both std::get and myns::get participate in overload resolution. Since that's a little loosey-goosey, it might be better to have myns::get delegate to std::get for the cases it can't handle, etc. Now, if you have a template that expects to call std::get it won't find your functionality, but if it wants non-standard behavior, it should call something other than std::get.

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.