有没有办法在c ++中使用模板函数

时间:2013-06-20 01:17:35

标签: c++ templates

我目前正在编写一些代码来将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作为我的返回类型,但这似乎是正确的方法。看起来我要求很多编译器,看起来我不得不恢复为简单地取消引用smartpointer以进行数组访问!

3 个答案:

答案 0 :(得分:3)

传统的C ++ 03方法是使用typedef,通常名为value_type。在C ++ 11中,我们可以使用autodecltype对此进行改进。以下示例修改为同时使用:

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 data更改为T* data并从实例化中的参数中删除*。顺便说一句,你的(T*)演员是错的,我也删掉了。

答案 1 :(得分: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;
}

答案 2 :(得分:1)

已经有一段时间了,但我过去经常这么做。以下内容应该有效:

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