У меня есть переменная типа Blah
,
Я хочу бросить это char[sizeof(blah)]
без копирования.
Мне нужно, чтобы приведение типа было достаточно сильным, чтобы создать экземпляр шаблона, который ожидает char[N]
,
Я перепробовал много вещей, но я не совсем понял.
Я хочу, чтобы что-то вроде этого работало правильно:
class Blah {
int a;
};template <typename T>
void foo (T& a)
{
//Not an array
}
template <int N>
void foo (char(&a)[N])
{
//an array!
}
Blah b;
foo(b); //not an array
foo((char[sizeofBlah])b); //hopefully treated as an array
Вы можете сделать это с reinterpret_cast<char (&)[sizeof b]>(b)
, но я не рекомендую это.
Вы не можете выполнять такое приведение, которое не имеет смысла. Что ты Можно сделать, это получить адрес объекта и переинтерпретировать адрес как адрес байта:
char* const buf = reinterpret_cast<char*>(&obj);
Это должно соответствовать вашим требованиям, но остерегайтесь использования терминологии «приведение к char[]
«Потому что это запутывает фактическую операцию, которая происходит.
Конечно, вы также можете интерпретировать адрес как начальный адрес буфера фиксированного размера:
using buffer_t = char[sizeof(Blah)];
buffer_t* pbuf = reinterpret_cast<buffer_t*>(&obj);
Но обратите внимание, что вы все еще используете указатель в буфер здесь.
Самый простой способ — добавить это как операцию в класс:
class Blah {
int a;
public:
void serialize(char *output) { output[0] = a; /* add others as needed */ }
};
Blah blah;
char buffer[sizeof(Blah)];
blah.serialize(buffer);
Это позволит вам явно видеть, что происходит, и централизовать код на случай, если вам потребуется изменить его позже.
Редактировать: интерфейс сериализации не очень элегантный (или очень безопасный) в моем примере, но я хочу добавить его в качестве метода.