c++ - 访问基类型数组成员(Int-to-Type 习语)

标签 c++ arrays templates

在尝试实现 Int-to-Type 习语时,我在继承的类中遇到了一个问题,即使尝试了此处其他帖子中的几个类似解决方案,我也无法解决该问题。我试图在继承类中的数组上实现一个简单的排序算法。首先,我设置了 int-to-type 枚举和结构:

enum class Technique : int
{
    NOOP,
    INSERTION_SORT,
    QUICK_SORT
};
template <Technique I>
struct AutoTechnique
{
    enum { value = I };
};

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

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) 并使用 -> 访问该值,但上面两行的代码似乎有效,但我没有这样做,并且尝试取消引用该对象的几种变体都没有奏效。

似乎主要问题在于尝试将 this[j] 中的值分配给 T temp。我试过类型转换 (T)this[j]我得到一个错误 type cast cannot convert...

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

最佳答案

让我举个例子...

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 的内存位置取消引用它对象(你只有一个,而不是它们的数组)。实际上您正在越界访问并且您的代码具有未定义的行为。

错误信息实际上解释了问题所在:

= cannot convert from Array to T

因为这里

temp = this[j];

temp当然是T同时 this[j] == *(this + j) ,即你增加 this指针 j -乘以sizeof(Array<int,49>) (这就是将整数添加到特定类型的指针时发生的情况)然后取消引用指针以获得 Array<int,49> .这些类型没有赋值运算符,因此会出现错误。

此外,没有Array<int,49>在那个内存位置。实际上你很幸运得到一个编译器错误,通常未定义的行为更隐蔽,隐藏在看似无辜的警告背后,或者更糟糕的是没有警告并且看起来有效但实际上没有。

关于c++ - 访问基类型数组成员(Int-to-Type 习语),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54298055/

相关文章:

c++ - 无符号长整型和位移位

c++ - 为什么这个 C++ ASIO,BEAST 服务器在执行 HTTPS/SSL 请求时进入错误状态

c++ - 查找数组其余部分的最大值

javascript - 如果数组包含特定值,则返回该值的完整 'content'

c++ - 如何将参数的 a::std::vector 绑定(bind)到仿函数?

c++ - 在 Gnome 或 KDE 中以编程方式在桌面上移动应用程序窗口

c++ - 方法未在 switch 语句中调用

javascript - 在数组中找到最大的 d 使得 a + b + c = d

c++ - 什么是 POI,它是什么意思?

c# - 使用 C# 从 MS Word 中的加载项访问 RichTextContentControl 文本