2

我想就模板参数重载模板类的 [] 运算符。像这样:

template<
    typename T,
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2>
class a_map 
{
public:
    const Property<T>& operator[](const Key1<T>& k) const
    { return _values[k.index()]; }
    const Property<T>& operator[](const Key2<T>& k) const
    { return _values[k.index()]; }
protected:
    std::vector<Property<T> > _values;
};

我会像这样使用这个类:

int main()
{
    a_map<float, prop, key_a, key_b> pm;
}

基本上我希望能够访问_values向量内的元素,而不必担心Key类型。重要的是他们有一个index()成员。

但是我收到以下错误

错误 C2535:'const Property &a_map::operator [](const Key1 &) const':成员函数已定义或声明

即使key_akey_b是两个完全不同类型的类模板。

我错过了什么吗?编译器是否害怕在某些情况下Key1<T>并且Key2<T>实际上可能是同一类型?

编辑 这些是使用的类模板main

template<typename T>
struct prop 
{
    T weight;
    T height;
};


template<typename T>
class key_a
{
public:
    int index() { return _i; }
private:
    int _i;
};

template<typename T>
class key_b
{
public:
    int index() { return 3; } // Always return 3

编辑 我正在使用 MVC++ 2008 编译器。

4

3 回答 3

1

由于除了参数类型之外,您的两个 operator[] 都是相同的,为什么不将它们模板化呢?

    template <typename TT>
    const Property<T>& operator[](const TT& k) const
    {
        return _values[k.index()];
    }
于 2012-07-21T21:22:43.407 回答
1

您需要声明您的index()函数,const因为在a_map模板内部您通过const对象调用它们

template<typename T> class key_a {
public:
    int index() const // <- `const` is necessary
      { return _i; }
private:
    int _i;
};

template<typename T> class key_b {
public:
    int index() const // <- `const` is necessary
      { return 3; } 
};

但除此之外,一切都可以编译并且对我来说工作正常。


在 VS2010 编译器中尝试过,得到和你一样的错误。这显然是 MSVC++ 编译器中的编译器错误。模板模板参数的处理不正确。

为了解决这个问题,我能够使用这种技术

template<
    typename T,
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2>
class a_map 
{
public:
    const Property<T>& operator[](const typename Key1<T>::self& k) const
    { return _values[k.index()]; }
    const Property<T>& operator[](const typename Key2<T>::self& k) const
    { return _values[k.index()]; }
protected:
    std::vector<Property<T> > _values;
};

并将关键模板定义为

template<typename T> class key_a {
public:
    typedef key_a self;
    int index() const { return _i; }
private:
    int _i;
};

template<typename T> class key_b {
public:
    typedef key_b self;
    int index() const { return 3; } 
};

这是不优雅的,但它使它与 MSVC++ 编译器一起正常工作。

于 2012-07-21T21:28:06.997 回答
0

像这样编译得很好...注意应该如何定义 Prop/K1/K2。

#include <vector>

template<
    typename T,
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2>
class a_map 
{
public:
    const Property<T>& operator[](const Key1<T>& k) const
    { return _values[k.index()]; }
    const Property<T>& operator[](const Key2<T>& k) const
    { return _values[k.index()]; }
protected:
    std::vector<Property<T> > _values;
};

template <typename T> struct K1 { int index() const { return 0; } };
template <typename T> struct K2 { int index() const { return 0; } };
template <typename T> struct Prop { };

int main()
{
    a_map<float, Prop, K1, K2> m;
}
于 2012-07-21T21:14:27.567 回答