1

我目前正在编写一些代码来将 java 代码转换为 c++ 代码,因此最终会遇到一些非常棘手的问题。我的问题是,是否有可能有一个从包含类返回模板化值的重载运算符?

即:我希望能够对以下课程进行以下操作。

SmartPointer<ArrayClass<bool>*> boolArray = new ArrayClass<bool>(true, true, false, false);
bool b = boolArray[1];


template <typename T> class SmartPointer
{
    T data;

    template <typename U>
    U operator [](int i) const
    {
        return ((*T)(*data))[index];
    }
}

template ArrayClass<U>
{
    // Various constructors...

    U operator [](int i) const
    {
        // Implementation here
    }
}

我得到的问题(可以理解)是:错误 C2783:'U SmartPointer::operator const':无法推断出'U'的模板参数编译器不知道 U 是什么,我希望能够告诉它它是bool - 因为这是 ArrayClass 将返回的内容。SmartPointer 可能不包含数组,在这种情况下 [] 运算符没有意义。但是我希望能够将它传递给智能指针内的对象,以防万一......?

我不知道该怎么做才能完成这项工作。也许不可能??

回答:

感谢大家的回复。提供了 3 个基本相同的解决方案,但我已将其授予 Oktalist,因为他是第一个。不过,我仍然对这个解决方案有困难,因为我正在将指针传递给我的 SmartPointer 类以允许我使用前向声明的类。这阻止了我使用 T::value_type 作为我的返回类型,但这似乎是正确的方法。看起来我对编译器的大部分要求,而且看起来我必须恢复到简单地取消引用智能指针才能进行数组访问!

4

3 回答 3

3

传统的 C++03 方式是使用 typedef,通常命名为value_type. auto在 C++11 中,我们可以使用和对此进行改进decltype。这是您的示例修改为同时使用:

SmartPointerCPP03<ArrayClass<bool>> boolArray = new ArrayClass<bool>(true, true, false, false);
SmartPointerCPP11<ArrayClass<bool>> boolArray = new ArrayClass<bool>(true, true, false, false);
bool b = boolArray[1];

template <typename T> class SmartPointerCPP03
{
    T* data;

    typename T::value_type operator [](int i) const
    {
        return (*data)[i];
    }
}

template <typename T> class SmartPointerCPP11
{
    T* data;

    auto operator [](int i) const -> decltype(std::declval<T>()[i])
    {
        return (*data)[i];
    }
}

template <typename T> class SmartPointerCPP14
{
    T* data;

    auto operator [](int i) const
    {
        return (*data)[i];
    }
}

template <typename U> ArrayClass
{
    // Various constructors...

    typedef U value_type;

    U operator [](int i) const
    {
        // Implementation here
    }
}

我还冒昧地将实例化中的参数更改T dataT* data和删除*。顺便说一句,你的(T*)演员表错了,我也删除了。

于 2013-06-20T01:40:42.407 回答
2

首先,让 SmartPointer 接受非指针类型:

SmartPointer<ArrayClass<bool> > boolArray = new ArrayClass<bool>(true, true, false, false);

将 typedef 添加到 ArrayClass:

template <typename U> class ArrayClass
{
    typedef U value_type;
    ...
};

然后编写一个元函数来获取类型:

template <typename T> struct ValueTypeOf {
    typedef typename T::value_type type;
};

然后在 SmartPointer 中使用它:

template <typename T> 
class SmartPointer
{
    typedef typename ValueTypeOf<T>::type value_type;

    T* data;

    value_type operator [](int i) const
    {
        return ((*data))[index];
    }
};

通过使用 ValueTypeOf 元函数,您可以根据类型对其进行专门化,因此如果您的类型没有 value_type 成员,您可以做一些不同的事情来获得它。

编辑:专门针对指针类型示例:

struct A {
    typedef int value_type;
};

template <typename T>
struct ValueTypeOf
{
    typedef typename T::value_type type;
};

template <typename T>
struct ValueTypeOf<T*>
{
    typedef typename T::value_type type;
};


int main()
{
    ValueTypeOf<A>::type  foo = 0; // foo is an int
    ValueTypeOf<A*>::type bar = 0; // bar is an int

    return 0;
}
于 2013-06-20T01:40:46.623 回答
1

已经有一段时间了,但我曾经做过很多这样的事情。像下面这样的东西应该可以工作:

在 ArrayClass 中定义一个名为 value_type 的 typedef,并将 typedef U 定义为那个。然后使用 T::value_type 作为 SmartPointer 中 operator [] 的返回类型。

于 2013-06-20T01:40:51.470 回答