首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问基类型数组成员(Int-to-Type惯用法)

访问基类型数组成员(Int-to-Type惯用法)
EN

Stack Overflow用户
提问于 2019-01-22 05:33:22
回答 2查看 66关注 0票数 0

在尝试实现Int- to -Type习惯用法时,我在继承的类中遇到了一个问题,即使在尝试了其他文章中的几个类似解决方案后,我也无法解决这个问题。我正尝试在继承类中的数组上实现一个简单的排序算法。首先,我设置int- To -type枚举和struct:

代码语言:javascript
复制
enum class Technique : int
{
    NOOP,
    INSERTION_SORT,
    QUICK_SORT
};
template <Technique I>
struct AutoTechnique
{
    enum { value = I };
};

接下来,我定义了继承自std::array的Array类,并使用一些工具来处理基于集合大小的不同排序技术:

代码语言:javascript
复制
template <typename T, unsigned N>
class Array : public std::array<T, N>
{
    static const Technique technique = (N == 0 || N == 1) ? Technique::NOOP :
        (N < 50) ? Technique::INSERTION_SORT : Technique::QUICK_SORT;

    void sort(AutoTechnique<Technique::NOOP>)
    {
        std::cout << "NOOP\n";
    }
    void sort(AutoTechnique<Technique::INSERTION_SORT>)
    {
        int i, j;
        T temp;
        for (i = 1; i < N; i++)
        {
            j = i;
            while (j > 0 && this[j - 1] > this[j])
            {
                temp = this[j]; // Wants to assign Array<T,N> to temp, rather than value at index.
                this[j] = this[j - 1];
                this[j - 1] = temp;
                j--;
            }
        }
    }
    void sort(AutoTechnique<Technique::QUICK_SORT>)
    {
        std::cout << "QUICK_SORT\n";
    }
public:
    void Sort()
    {
        sort(AutoTechnique<technique>());
    }

};

问题出在注释行上,编译器告诉我"= cannot convert from Array<int,49> to T" (int,49是测试用例)。

我能找到的最好的答案是,我需要取消引用这个(* this )并使用->访问值,但上面两行代码似乎可以工作,而我没有这样做,并且尝试取消引用对象的几个变体都不起作用。

似乎主要的问题是试图将thisj中的值赋给T temp。我尝试强制转换(T)this[j],但得到一个错误,即type cast cannot convert...

如何将this数组索引中的值存储在与提供给该数组的类型相匹配的临时变量中?

EN

回答 2

Stack Overflow用户

发布于 2019-01-22 06:04:44

让我举个例子。

代码语言:javascript
复制
class foo {};

int main() {
    foo* a;
    a+5;       // fine ? 
    a[3];      // fine ? 
    foo b;
    b+5;       // error: no operator found
    b[3];      // error: no operator found
}

有一些用于指针的运算符(该示例并不完整,其目的只是为了证明它们不是用于对象的运算符)。它们适用于任何类型的指针。您正在将指针上的操作与实例上的操作联系在一起。比较指针与比较对象是不同的。

此外,当a是一个指针时,a[b]就是*(a+b)。因此,在您的代码中,它看起来是有效的,但实际上并不有效。您将this视为指向一个对象数组的指针,然后在没有Array对象的内存位置(只有一个对象,而不是一个对象数组)取消对它的引用。实际上,您正在访问越界,并且您的代码具有未定义的行为。

错误消息实际上解释了错误的原因:

=无法从数组转换为T

因为在这里

代码语言:javascript
复制
temp = this[j];

temp当然是一个T while this[j] == *(this + j),也就是你将this指针通过j-times sizeof(Array<int,49>)递增(这就是当你将一个整数加到某个特定类型的指针上时发生的事情),然后你解除对指针的引用,得到一个Array<int,49>。这些类型没有赋值运算符,因此出现错误。

此外,在该内存位置没有Array<int,49>。实际上,你很幸运得到了一个编译器错误,通常未定义的行为更隐蔽,隐藏在看起来是无害的警告后面,或者更糟糕的是没有警告,当它实际上不是工作的时候,看起来像是在工作。

票数 2
EN

Stack Overflow用户

发布于 2019-01-23 02:31:57

根据@NathanOliver提供的答案更新代码

代码语言:javascript
复制
void sort(AutoTechnique<Technique::INSERTION_SORT>)
{
    int i, j;
    T temp;
    for (i = 1; i < N; i++)
    {
        j = i;
        while (j > 0 && (*this)[j - 1] > (*this)[j])
        {
            temp = (*this)[j];
            (*this)[j] = (*this)[j - 1];
            (*this)[j - 1] = temp;
            j--;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54298055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档