尝试实现Int-to-Type习惯用法,我在继承的类中遇到了一个问题,即使尝试了此处其他文章中的几种类似解决方案,我也无法解决。我正在尝试在继承的类中的数组上实现简单的排序算法。首先,我设置int-to-type枚举和struct:
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
数组的索引中,该索引与提供给数组的类型匹配的临时变量中?
答案 0 :(得分:2)
让我举个例子...
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
因为这里
temp = this[j];
temp
当然是T
,而this[j] == *(this + j)
是this
乘以j
-sizeof(Array<int,49>)
倍(即将整数添加到某种类型的指针,然后取消引用该指针以获得Array<int,49>
时会发生什么。这些类型没有赋值运算符,因此会出现错误。
此外,该存储位置中没有Array<int,49>
。实际上,您很幸运地遇到了编译器错误,通常未定义的行为更加笨拙,隐藏在无辜的警告之下,甚至更糟的是没有警告,而实际上却没有警告。
答案 1 :(得分:0)
@NathanOliver提供的答案中的更新代码
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--;
}
}
}