C++ 访问基类型数组成员(Int-to-type习惯用法)
在尝试实现Int-to-Type习惯用法时,我在继承的类中遇到了一个问题,即使在这里的其他文章中尝试了几个类似的解决方案,我也无法解决这个问题。我试图在继承类中的数组上实现一个简单的排序算法。首先,我将int设置为类型enum和struct:C++ 访问基类型数组成员(Int-to-type习惯用法),c++,arrays,templates,C++,Arrays,Templates,在尝试实现Int-to-Type习惯用法时,我在继承的类中遇到了一个问题,即使在这里的其他文章中尝试了几个类似的解决方案,我也无法解决这个问题。我试图在继承类中的数组上实现一个简单的排序算法。首先,我将int设置为类型enum和struct: enum class Technique : int { NOOP, INSERTION_SORT, QUICK_SORT }; template <Technique I> struct AutoTechnique {
enum class Technique : int
{
NOOP,
INSERTION_SORT,
QUICK_SORT
};
template <Technique I>
struct AutoTechnique
{
enum { value = I };
};
enum类技术:int
{
努普,
插入排序,
快速排序
};
模板
结构自动技术
{
枚举{value=I};
};
接下来,我使用一些工具定义从std::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>());
}
模板
类数组:public std::Array
{
静态常量技术技术=(N==0 | | N==1)?技术::NOOP:
(N<50)?技术::插入\排序:技术::快速\排序;
无效排序(自动技术)
{
std::cout 0&&this[j-1]>this[j])
{
temp=this[j];//希望将数组分配给temp,而不是索引处的值。
这个[j]=这个[j-1];
这个[j-1]=温度;
j--;
}
}
}
无效排序(自动技术)
{
std::cout,但上面两行代码似乎可以工作,我没有这样做,并且尝试取消引用对象的一些变体也不起作用
似乎主要的问题是试图将此[j]中的值分配给T temp。我尝试转换(T)此[j]
,我得到一个错误,类型转换无法转换…
如何将此
数组的索引中的值存储在与提供给数组的类型匹配的临时变量中?让我使用一个示例
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)
。因此,在代码中,它似乎有效,但实际上无效。您将此
视为指向对象数组的指针,然后在没有数组
对象的内存位置取消对它的引用(您只有一个,而不是一个数组)。实际上,您正在访问越界,并且您的代码具有未定义的行为
错误消息实际上解释了错误的原因:
=无法从数组转换为T
因为这里
temp = this[j];
temp
当然是一个T
,而this[j]=*(this+j)
,即将this
指针增加j
——乘以sizeof(Array)
(这是将整数添加到特定类型的指针时发生的情况)然后取消对指针的引用,得到一个数组
。这些类型没有赋值运算符,因此出现错误
此外,该内存位置没有数组。事实上,您很幸运地得到了一个编译器错误,通常未定义的行为更隐蔽,隐藏在看似无辜的警告后面,或者更糟糕的是,隐藏在没有警告的情况下,并且在实际没有警告的情况下似乎有效。让我举一个例子
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)
。因此,在代码中,它似乎有效,但实际上无效。您将此
视为指向对象数组的指针,然后在没有数组
对象的内存位置取消对它的引用(您只有一个,而不是一个数组)。实际上,您正在访问越界,并且您的代码具有未定义的行为
错误消息实际上解释了错误的原因:
=无法从数组转换为T
因为这里
temp = this[j];
temp
当然是一个T
,而this[j]=*(this+j)
,即将this
指针增加j
——乘以sizeof(Array)
(这是将整数添加到特定类型的指针时发生的情况)然后取消对指针的引用,得到一个数组
。这些类型没有赋值运算符,因此出现错误
此外,在那个内存位置并没有数组。实际上,你们很幸运地得到了一个编译器错误,通常未定义的行为更隐蔽,隐藏在看似无辜的警告后面,甚至更糟糕的是,并没有警告,当它实际不起作用时,它似乎起作用。根据@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--;
}
}
}
void排序(自动技术)
{
int i,j;
温度;
对于(i=1;i0&(*this)[j-1]>(*this)[j])
{
温度=(*此)[j];
(*此)[j]=(*此)[j-1];
(*此)[j-1]=温度;
j--;
}
}
}
根据@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--;
}
}
}
void排序(自动技术)
{
int i,j;
温度;
对于(i=1;i0&(*this)[j-1]>(*this)[j])
{
温度=(*此)[j];
(*此)[j]=(*此)[j-1];
(*此)[j-1]=温度;
j--;
}
}
}
这个[j]
即使正确,你为什么要写这样的代码?我觉得很困惑,应该是*(这个+j)
或者这个->操作符[](j)
?你找到的建议是正确的。你需要(*这个)