C++ Array Subscript Operator Template

2020-02-11 02:44发布

问题:

After trying to make access to a storage class a little easier, I ended up in a situation that I don't have a lot of knowledge on. And, finding people that are trying to do the same thing as me isn't easy.

What I'm trying to do, is have a class that stores an array of values as strings internally, but allows simple type casting from the user's end. What I had planned on doing is use the array subscript operator to return whichever type they specify through a template. Although, it sounds a lot better than it works in practice. Here's a simple example of what I'm doing, to give you an idea of how it should work.

class StringList
{
    public:
    template <typename T> 
    T operator[](const int i)
}

From there, I would define a few specific templates, and any user could very easily define more if needed. But, the biggest problem with this is, I don't know how to call the subscript operator with a template. At first I assumed the following(which apparently isn't correct), considering it's similar to the standard way of calling a template method.

StringList list;
T var = list<T>[0];

Does anyone know the proper way of calling the subscript operator as a template? Or, should I just avoid doing this, and use a named method?

回答1:

The only way calling your operator is explicitly writing list.operator[]<T>().

There are two basic ways out:

  1. Write a function template like list.get<int>() (as proposed by templatetypedef)
  2. Return a proxy with automatic conversation to T.

The code would look like:

// in the class
struct proxy {
  proxy(StringList *list, int i) : list(list), i(i) {}
  StringList *list;
  int i;
  template <typename T>
  operator T() { return list->get<T>(i); }
};

proxy operator[](int i) { return proxy(this, i); }

template <typename T> 
T get(int i) { return ...; T(); }

// how to use it:
StringList list;
int var = list.get<int>(0);
float var2 = list[0];


回答2:

I think there is no syntax to pass template parameters to the natural call of operator[]. You would probably need to call:

T var = list.operator[]<T>(0);

Like you do with normal template functions, so there is no point in using operator overload here.