#c #flatbuffers
Вопрос:
Это иногда вызывает проблемы с 64-разрядной компиляцией. Если нет особой причины, я думаю, что было бы лучше иметь согласованный тип индекса для VectorLength() и Vector::size().
В этом примере вызов print_first_n_of_inventory с длиной вектора требует приведения.
#include <flatbuffers/flatbuffers.h>
#include <tests/monster_test_generated.h>
#include <iostream>
using namespace flatbuffers;
using namespace MyGame::Example;
void print_first_n_of_inventory(const Vector<uint8_t> * pInventory, uoffset_t n)
{
for (uoffset_t i = 0; i < n; i)
{
auto val = pInventory->Get(i);
std::cout << val << "n";
}
}
int main(int, char * argv[])
{
auto * pMonster = GetMonster(argv[1]);
auto * pInventory = pMonster->inventory();
print_first_n_of_inventory(pInventory, 2);
print_first_n_of_inventory(pInventory, pInventory->size());
// warning C4267: 'argument': conversion from 'size_t' to 'flatbuffers::uoffset_t', possible loss of data
print_first_n_of_inventory(pInventory, VectorLength(pInventory));
return 0;
}
Комментарии:
1.
VectorLength
проверяет, что указанный указатель отсутствуетnullptr
, и преобразуетuoffset_t
возвращенноеsize()
значение вsize_t
. Возможно, чтобы упростить его использование в контекстах, отличных от flatbuffer, гдеsize_t
ожидается a, но, как вы заметили, это кажется ненужным. Было бы лучше использоватьuoffset_t
и то, и другое. Я бы использовал функцию-членsize()
напрямую, когда я уверенpInventory
, что это неnullptr
так, иuoffset_t
(что всегдаuint32_t
) требуется. Или добавьте это:template<typename T> static inline auto MyVectorLength(const Vector<T>* v) { return v ? v->size() : 0U; }
и используйте это вместо этого.2. Мой шаблон функции замены должен был быть следующим:
template<typename T> static inline auto MyVectorLength(const flatbuffers::Vector<T>* v) { return v ? v->size() : 0U; }
— Я забыл пространство имен.
Ответ №1:
Да, это прискорбно, но uoffset_t
это собственный тип того, как длина хранится в буферах, которые всегда 32-разрядные. Казалось, что лучше всего предоставить этот собственный тип, чем конвертировать в size_t
для пользователя, так как это приведет к двойному преобразованию в случае, когда 32-разрядные на самом деле были бы желательны.
Комментарии:
1. Как вы думаете, это можно и нужно изменить? Это может привести к другому типу, выведенному с помощью автоматического вывода типа или кода шаблона, но в противном случае должно быть неявно преобразовано в size_t, как сейчас внутри функции.