使用模板对象重载operator []以获取容器类

时间:2014-08-17 13:34:36

标签: c++ templates operator-overloading

首先,我有一个模板类,如下所示:

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;}
};

我还有一个名为Config的容器类,它有几个不同的可配置列表,用于存储可配置的int,bools和浮点数。我想重载Config的[]运算符,以便它从其中一个列表返回一个具有给定名称(不论其类型)的Configurable,但这似乎不起作用:

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

编译器返回&#39;不匹配operator []&#39;的错误。所以我的问题是 - 我怎样才能做到这一点?甚至可以使用模板来实现它,还是应该找到一种不同的继承方法?

编辑:抱歉所有的困惑。这是我正在谈论的容器类:

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 );
};

2 个答案:

答案 0 :(得分:0)

如上所述,它是语法错误。

你写的时候:

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

您尝试定义一个独立的操作员[],好像它是一个独立的功能 但根据您的解释,operator []应该是您的容器配置的成员。

所以它的定义应该看起来像:

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

通过这样的定义,这些东西可以编译,你可以用它来代替:

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

    auto a = cfg["test"]; 
}

答案 1 :(得分:0)

在没有任何依赖于模板参数的参数的情况下声明模板operator[]的问题是编译器无法以T形式确定调用中的config["name"]类型。 考虑到代码可读性,一种解决方案是将operator[]更改为方法,例如:

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

然后,调用应该写成:

config.get<int>("name")

另外,请考虑通过引用(const std::string&)传递字符串,以避免传递给方法/运算符的std::string的不必要副本。