C++ :: 安全地使用 reinterpret_cast 生成 "wrapper" 迭代器
C++ :: Safely using reinterpret_cast to generate "wrapper" iterators
我有一个包含给定原始类型值的向量,但我想迭代此向量,以便我可以执行某些操作 "as if" 使用包装值类型的 class。
以下代码示例编译并产生预期结果:
#include <iostream>
#include <vector>
template<class T>
struct wrap
{
T x;
void print() const
{
if (x < 0)
std::cout << " negative ";
else if (x > 0)
std::cout << " positive ";
else
std::cout << " --null-- ";
}
void operator ++ ()
{
if (this->x < static_cast<T>(0))
this->x += static_cast<T>(1000);
}
};
int main()
{
using vec_t = std::vector<int>;
vec_t v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
// essential piece of code
using vec_w = std::vector< wrap<int> >;
vec_w::iterator it = reinterpret_cast<vec_w*>(&v)->begin();
vec_w::iterator ti = reinterpret_cast<vec_w*>(&v)->end();
while (it != ti)
{
it->print();
++(*it);
it->print();
std::cout << std::endl;
++it;
}
return 0;
}
输出:
negative negative
positive positive
negative positive
--null-- --null--
但是只要包装器定义了完全相同的值类型(没有别的),这样使用就安全吗?
But is this safe to use, as long as the wrapper defines the exact same value type (and nothing else)?
没有。您违反了严格的别名规则。
为什么不换行 T&
?
template<class T>
struct wrap
{
T& x;
void print() const
{
if (x < 0)
std::cout << " negative ";
else if (x > 0)
std::cout << " positive ";
else
std::cout << " --null-- ";
}
void operator ++ ()
{
if (this->x < static_cast<T>(0))
this->x += static_cast<T>(1000);
}
};
你可以在一个循环中换行
int main()
{
std::vector<int> v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
for (auto & i : v)
{
wrap<int> w { i };
w.print();
++w;
w.print();
std::cout << std::endl;
}
return 0;
}
或者有一个包裹的向量
int main()
{
std::vector<int> v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
std::vector<wrap<int>> w { v.begin(), v.end() };
for (auto & i : w)
{
i.print();
++i;
i.print();
std::cout << std::endl;
}
return 0;
}
我有一个包含给定原始类型值的向量,但我想迭代此向量,以便我可以执行某些操作 "as if" 使用包装值类型的 class。
以下代码示例编译并产生预期结果:
#include <iostream>
#include <vector>
template<class T>
struct wrap
{
T x;
void print() const
{
if (x < 0)
std::cout << " negative ";
else if (x > 0)
std::cout << " positive ";
else
std::cout << " --null-- ";
}
void operator ++ ()
{
if (this->x < static_cast<T>(0))
this->x += static_cast<T>(1000);
}
};
int main()
{
using vec_t = std::vector<int>;
vec_t v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
// essential piece of code
using vec_w = std::vector< wrap<int> >;
vec_w::iterator it = reinterpret_cast<vec_w*>(&v)->begin();
vec_w::iterator ti = reinterpret_cast<vec_w*>(&v)->end();
while (it != ti)
{
it->print();
++(*it);
it->print();
std::cout << std::endl;
++it;
}
return 0;
}
输出:
negative negative
positive positive
negative positive
--null-- --null--
但是只要包装器定义了完全相同的值类型(没有别的),这样使用就安全吗?
But is this safe to use, as long as the wrapper defines the exact same value type (and nothing else)?
没有。您违反了严格的别名规则。
为什么不换行 T&
?
template<class T>
struct wrap
{
T& x;
void print() const
{
if (x < 0)
std::cout << " negative ";
else if (x > 0)
std::cout << " positive ";
else
std::cout << " --null-- ";
}
void operator ++ ()
{
if (this->x < static_cast<T>(0))
this->x += static_cast<T>(1000);
}
};
你可以在一个循环中换行
int main()
{
std::vector<int> v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
for (auto & i : v)
{
wrap<int> w { i };
w.print();
++w;
w.print();
std::cout << std::endl;
}
return 0;
}
或者有一个包裹的向量
int main()
{
std::vector<int> v;
v.push_back(-1234);
v.push_back( 5678);
v.push_back(-4);
v.push_back(0);
std::vector<wrap<int>> w { v.begin(), v.end() };
for (auto & i : w)
{
i.print();
++i;
i.print();
std::cout << std::endl;
}
return 0;
}