我将代码转移到Ubuntu 4.4.1 g ++编译器。虽然如下所示重载operator ++ (int)
,但它会导致(T*)
出错,但适用于(T*&)
。在我的早期版本(linux-64,但不记得确切的版本)它也适用于(T*)
。
任何原因,为什么?
template<typename T>
struct Wrap
{
void *p; // Actually 'p' comes from a non-template base class
Wrap<T>& operator ++ ()
{
((T*)p) ++; // throws error; if changed to (T*&) then ok!
return *this;
}
// ...
};
int main ()
{
Wrap<int> c;
++c; // calling prefix increment
}
答案 0 :(得分:2)
类型转换的结果不是左值,因此无法分配和(内置)++是一种赋值形式。如果它有用的话,这是编译器中的一个错误。
参考它编译(效果与*(T**)&p
相同),但由于别名规则(编译器可能会认为不同类型的指针(和引用)不指向同一个对象)它是正式无效,但它适用于所有已知的编译器。
最干净的方式:
p = static_cast<void *>(static_cast<T *>(p) + 1)
(从不在C ++中使用C风格的强制转换)并依赖编译器能够以与++
完全相同的方式编译它。但是,如果你在定义指针时有模板参数(在你做的示例代码中),那么使用正确的类型指针会更好(我会说它也适用于成员指针,但它们没有意义++
)。
答案 1 :(得分:1)
看起来你混淆了你的前缀和后缀增量签名。另外,如果你知道你的类型是T,为什么要使用void *?
请参阅以下相应的签名: http://www.codeguru.com/forum/showthread.php?t=231051