简体   繁体   中英

Overloading operator[] for a container class with template objects

First of all, I have a template class that looks like this:

template <typename T>
class Configurable
{
    public:
    //protected:
        T var_value;
        std::string var_name;
        std::string var_type;

        Configurable()
        : var_value(0), var_name("unnamed"), var_type("undefined")
        {}
        Configurable( T v_value, std::string v_name, std::string v_type )
        : var_value(v_value), var_name(v_name), var_type(v_type)
        {}

        std::string get_name() {return var_name;}
};

I also have a container class named Config which has a couple of different Configurable lists for storage of Configurable ints, bools and floats. I want to overload the [] operator of Config so that it returns a Configurable with the given name (regardless of the type) from one of the lists, but this doesn't seem to work:

template <typename T>
Configurable<T>& operator[] ( const std::string v_name_arg );

The compiler returns an error of 'no match for operator[]'. So my question is - how can I make this work? Is it even possible to do it using templates or should I find a different approach with inheritance?

EDIT: Sorry for all the confusion. Here's the container class I'm talking about:

class Config
{
    public:
    //private:
    std::list < Configurable<int>    > list_int;
    std::list < Configurable<float>  > list_float;
    std::list < Configurable<double> > list_double;
    std::list < Configurable<bool>   > list_bool;

    //public:
    Config(){}

    template <typename T>
    Configurable<T>& operator[] ( const std::string &v_name_arg );
};

As described above, it's a syntax error.

WHen you write:

template <typename T>
Configurable<T>& operator[] ( const std::string v_name_arg );

You try to define a free standing operator[] as if it would be a free standing function.
But according to your explanations, operator[] should be a member of your container Config.

So the its definition should look somewhat like:

template <typename T>
class Config {
    //...
public:
    Configurable<T>& operator[] (const std::string v_name_arg) { /* return a ref to a Configurable */ };
};

With such a definition, the stuff compiles, and you can use it for example with :

int main()
{
    Configurable<int> c; 
    Config<int> cfg; 

    auto a = cfg["test"]; 
}

The problem with declaring the templated operator[] without any argument that depends on the template parameter is that the compiler cannot determine the type T from a call in the form config["name"] . One solution, considering code readability, would be changing the operator[] to a method such as:

template <typename T>
Configurable<T>& get ( const std::string v_name_arg );

Then, the call should be written like:

config.get<int>("name")

Also, consider passing the string by reference ( const std::string& ) to avoid unnecessary copies of a std::string passed to the method/operator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM