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;
}