Стандартный тип макета и reinterpret_cast - PullRequest
1 голос
/ 22 сентября 2011

Могу ли я приводить из своего класса в структуру, если я скопировал членов структуры в мой класс?

#include <stdint.h>
#include <sys/uio.h>

class Buffer
{
public:
    void * address;
    size_t size;

    Buffer(void * address = nullptr, size_t size = 0)
        : address(address), size(size)
    {
    }

    operator iovec *() const
    {
        // Cast this to iovec. Should work because of standard layout?
        return reinterpret_cast<iovec *>(this);
    }
}

1 Ответ

4 голосов
/ 22 сентября 2011

Во-первых, вы не можете выбросить константу:

§5.2.10p2.Оператор reinterpret_cast не должен отбрасывать константу (§5.2.11).(...)

Так что вам нужно хотя бы написать это как

operator iovec const*() const
{
    return reinterpret_cast<iovec const*>(this);
}

или

operator iovec *()
{
    return reinterpret_cast<iovec *>(this);
}

Кроме того, вам нужнои Buffer, и iovec должны быть типами стандартной компоновки, а iovec не может иметь более строгую (т.е. большую) юстировку, чем Buffer.

§5.2.10p7.Указатель на объект может быть явно преобразован в указатель на объект другого типа.Когда значение v типа «указатель на T1» преобразуется в тип «указатель на cv T2», результат равен static_cast<cv T2*>(static_cast<cv void*>(v)), если оба T1 и T2являются типами стандартной компоновки (§3.9), и требования к выравниванию T2 не являются более строгими, чем требования T1, или если любой тип равен void.(...)

Вы также должны быть осторожны, чтобы не нарушить строгих правил псевдонимов : в общем, вы не можете использовать два указателя или ссылки на разные типы, которые относятся кта же ячейка памяти.

...