Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее:
enum class Type {int_, double_, string_};
struct Value {
Type type;
std::vector<uint8_t> v;
};
Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах, так же в type находится маркер типа, как то можно исхитрится написать какой-то метод или шаблонный класс, что бы в метод получения значения подаешь экземпляр Value и получаешь значение нужного типа
к примеру:
auto val = GetValue(value);
и соответственно если value.type = Type::int_ val будет типа int и тд. ?
Здравствуйте, _agg, Вы писали:
_>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>
_>enum class Type {int_, double_, string_};
_>struct Value {
_> Type type;
_> std::vector<uint8_t> v;
_>};
_>
_>Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах, так же в type находится маркер типа, как то можно исхитрится написать какой-то метод или шаблонный класс, что бы в метод получения значения подаешь экземпляр Value и получаешь значение нужного типа _>к примеру: _>
_>auto val = GetValue(value);
_>
_>и соответственно если value.type = Type::int_ val будет типа int и тд. ?
Напрашивается что то вроде:
template<Type type> class GetValue {
public:
typedef int Result;
Result operator()(Value& val) {
return *(int*)val.v.data();
}
};
template<> class GetValue<Type::double_> {
public:
typedef double Result;
Result operator()(Value& val) {
return *(double*)val.v.data();
}
};
template<> class GetValue<Type::string_> {
public:
typedef std::string Result;
Result operator()(Value& val) {
return (char*)val.v.data();
}
};
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, _agg, Вы писали:
_>>любые предложения...
S>Почитать про std::variant и std::get.
Скопировав из std::vector<uint8_t> в std::variant нужно все равно распознавать тип и потом его возвращать, как вы будете возвращать разные типы из одной функции... Ваш ответ не решает вопроса, из-за 1)Лишнее копирование 2)Вопрос с выводом разных типов
Здравствуйте, _agg, Вы писали:
_>как вы будете возвращать разные типы из одной функции...
Я не буду. И вам бы не советовал, но есть подозрения, что к вменяемым советам вы не прислушаетесь.
_>Ваш ответ не решает вопроса
А на ваш вопрос нет вменяемого ответа. Но есть направление, в сторону которого можно было бы посмотреть.
_>2)Вопрос с выводом разных типов
Скорее с тем, что вы не можете сформулировать проблему. При этом есть подозрение о том, что вы не имеете представления о том, что можно сделать в языке со статической типизацией, а что нет.
Здравствуйте, _agg, Вы писали:
_>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>
_>enum class Type {int_, double_, string_};
_>struct Value {
_> Type type;
_> std::vector<uint8_t> v;
_>};
_>
_>Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах,
В каком формате? Big endian? little endian?
А в каком формате double_?
Или это число записанное символами в шестнадцатеричном коде?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, _agg, Вы писали:
_>>как вы будете возвращать разные типы из одной функции...
S>Я не буду. И вам бы не советовал, но есть подозрения, что к вменяемым советам вы не прислушаетесь.
_>>Ваш ответ не решает вопроса
S>А на ваш вопрос нет вменяемого ответа. Но есть направление, в сторону которого можно было бы посмотреть.
_>>2)Вопрос с выводом разных типов
S>Скорее с тем, что вы не можете сформулировать проблему. При этом есть подозрение о том, что вы не имеете представления о том, что можно сделать в языке со статической типизацией, а что нет.
Уважаемый проблему я четко сформулировал, насчет что можно, а что нельзя в языке со статической типизацией я тоже знаю, я и задаю вопрос что может есть какие-то приемы, паттерны проектирования которые позволят решить проблему, в текущей ситуации Value который содержит внутри маркер типа, что бы получить значение нужного типа придется каждый раз писать предикат позволяющий распознать тип и привести к нужному, хотелось бы избежать этого значительного куска кода.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _agg, Вы писали:
_>>>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>>>
_>>>enum class Type {int_, double_, string_};
_>>>struct Value {
_>>> Type type;
_>>> std::vector<uint8_t> v;
_>>>};
_>>>
_>>любые предложения... BFE>Помему Value::v не union?
_>>
_>>template<Type type> class GetValue {
_>>public:
_>> typedef int Result;
_>> Result operator()(Value& val) {
_>> return *(int*)val.v.data();
_>> }
_>>};
_>>
Выравнивание однобайтовое в настоящем коде, тут я привел тестовый пример небольшой отражающий суть возникшей проблемы, гарантии что в строке 0 есть, потому как при загрузке из файла происходит проверка на целостность... вообщем мне не нужна ваша проверка текущего тестового кода, этот код я написал что бы показать проблему... и проблема в том как избежать кода предиката при получении результирующего экземпляра типа, что бы был метод который возвращал уже то что нужно и все
Здравствуйте, _agg, Вы писали:
_>Уважаемый проблему я четко сформулировал,
Нет.
В нормальном случае число типа double никак не может оказаться внутри std::vector<uint8_t> в виде представления в памяти.
Что говорит либо о сериализации, либо о передаче данных в бинарном протоколе.
В обоих случаях вопрос подобного рода — маркер кривого решения.
Здравствуйте, _agg, Вы писали:
_>Уважаемый проблему я четко сформулировал,
В вашей формулировке у вашего вопроса нет вменяемого ответа. Тип переменной должен быть определен в compile-time. Вы не можете в C++ сделать переменную val, которая в run-time может оказаться либо int, либо double, либо еще что-то. Если вам нужна переменная, которая может содержать значение одного из нескольких фиксированных (в compile-time типов), то это прямая дорога к std::variant или чему-то подобному.
Но вы, очевидно, излишне самоуверены, чтобы прислушиваться к чужому мнению.
_>насчет что можно, а что нельзя в языке со статической типизацией я тоже знаю
Хотелось бы пруфов.
_>я и задаю вопрос что может есть какие-то приемы, паттерны проектирования которые позволят решить проблему
Во-первых, у вас не получилось толком сформулировать проблему, которую вы хотите решить.
Во-вторых, тут уже упомянули std::visit. Как раз тот самый паттерн, который мог бы помочь. Но решение будет выглядеть вовсе не как `auto val =...`;
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _agg, Вы писали:
_>>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>>
_>>enum class Type {int_, double_, string_};
_>>struct Value {
_>> Type type;
_>> std::vector<uint8_t> v;
_>>};
_>>
_>>Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах, BFE>В каком формате? Big endian? little endian? BFE>А в каком формате double_? BFE>Или это число записанное символами в шестнадцатеричном коде?
Это не имеет значения никакого к описанной проблеме, нужен какой-то прием который позволит вывести нужный тип...
Здравствуйте, _agg, Вы писали:
_>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>
_>enum class Type {int_, double_, string_};
_>struct Value {
_> Type type;
_> std::vector<uint8_t> v;
_>};
_>
_>Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах, так же в type находится маркер типа, как то можно исхитрится написать какой-то метод или шаблонный класс, что бы в метод получения значения подаешь экземпляр Value и получаешь значение нужного типа
...
Здравствуйте, _agg, Вы писали:
_>Выравнивание однобайтовое в настоящем коде, тут я привел тестовый пример небольшой отражающий суть возникшей проблемы, гарантии что в строке 0 есть, потому как при загрузке из файла происходит проверка на целостность... вообщем мне не нужна ваша проверка текущего тестового кода, этот код я написал что бы показать проблему... и проблема в том как избежать кода предиката при получении результирующего экземпляра типа, что бы был метод который возвращал уже то что нужно и все
Ясно.
Проблема о которой вы пишите — это не проблема: как хотите, так и пишите.
Если это серьёзный проект, то настоящие проблемы ждут впереди: несовместимость версий и непереносимость файлов.
Интересно, а чем вы руководствовались при выборе именно бинарного формата записи файла?
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, _agg, Вы писали:
_>>Всем привет, возник вопрос существует ли какой-нибудь прием что бы осуществить следующее: _>>
_>>enum class Type {int_, double_, string_};
_>>struct Value {
_>> Type type;
_>> std::vector<uint8_t> v;
_>>};
_>>
_>>Есть вот такое Value указанное выше, соответственно в векторе v находится значение в байтах, так же в type находится маркер типа, как то можно исхитрится написать какой-то метод или шаблонный класс, что бы в метод получения значения подаешь экземпляр Value и получаешь значение нужного типа _>...
_>https://en.cppreference.com/w/cpp/utility/variant/visit#Example
Здравствуйте, _agg, Вы писали:
_>Выравнивание однобайтовое в настоящем коде, тут я привел тестовый пример небольшой отражающий суть возникшей проблемы, гарантии что в строке 0 есть, потому как при загрузке из файла происходит проверка на целостность... вообщем мне не нужна ваша проверка текущего тестового кода, этот код я написал что бы показать проблему... и проблема в том как избежать кода предиката при получении результирующего экземпляра типа, что бы был метод который возвращал уже то что нужно и все
Как обычно: добавляете метод Get() который возвращает объект типа X. У объекта типа X перегружаете операторы преобразования типа explicit operator int();, explicit operator double(); и explicit operator std::string();.