Как сохранить какой-то" null " в переменной c++ double или int?

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

struct A {
     double a1;
     int b1;
     double a2;
     int b2;
};

я должен прочитать значения файла для a1, b1, a2 и b2. Большую часть времени все четыре числа находятся в файле, но иногда есть только два числа.

когда есть два числа, я хочу сохранить значения в a1 и b1 и я хочу сохранить "ничего" в a2 и b2. Если a2 и b2 были указатели, я мог бы просто назначить их nullptr, но они не указатели.

есть ли что-то, что я могу хранить в double и int переменные, указывающие, что "ничего" не хранится?

Я знаю Boost.Optional доступно, но я пытаюсь избежать этой библиотеки.

8 ответов


вы можете назначить NAN двойному a2, что также указывает на недопустимость int b2.

на этой странице для использования NAN.


либо у вас есть значение, которое не является законным, либо нет. Если у вас есть значение, которое не является законным (например, -1), используйте его в качестве часового. Если нет, то нет. Использовать импульс.Необязательно или сверните свой собственный класс" value plus boolean".


нельзя. Я могу придумать два альтернативных способа:--1-->

  1. использовать int *; или
  2. используйте значение, которое наверняка недопустимо в вашем контексте. Например, если он никогда не может быть отрицательным, используйте -1 для указания null. Но я все же предпочитаю первый способ, так как его правильность не зависит от требования или контекста.

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

Я предлагаю завод и базовый класс. По сути, у вас будет как минимум два класса:

struct two_values
{
  double a1;
  int    b1;
};

struct four_values : public two_values
{
  double a2;
  int    b2;
};

когда функция явно требует четыре значения, используйте four_values структура в декларации. В противном случае используйте two_values структура в объявлении функции.

в этом отношении говорится, что a four_values экземпляр можно использовать в любой функции, требующей two_values структура.

альтернатива
Альтернативой является использование std::vector для вашего пользования:

struct Container
{
  std::vector<double> a_values;
  std::vector<int>    b_values;
};

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


  1. вы можете выбрать значение, которое не может быть в текстовых файлах (недопустимое значение), например 0, -1, std::numeric_limits<int>::max(). При обработке данных используйте значение, только если оно не равно незаконному значению (или sentinel).
  2. включить bool, указывающий, сколько значений есть:

    struct A {
        double a1;
        int b1;
        double a2;
        int b2;
        bool has_4_nums;
    };
    
  3. использовать указатель (int* или std::unique_ptr<int> согласно @Peter Pei Guo), и назначить nullptr, когда они отсутствуют.


у вас есть два варианта, чтобы избежать boost::optional и, следовательно, зависимость с Boost:

  • используйте компилятор std::experimental::optional, который доступен из GCC 4.9+ (и Clang в последних версиях IIRC) с -std=c++14.

  • используйте "эталонную реализацию" от Анджея Кшемежского для std::experimental::optional С GitHub. Это только заголовок, поэтому вы можете просто скопировать заголовок в свой проект (конечно, обращая внимание на лицензия)


кроме того, вы можете добавить дополнительный член, чтобы узнать, были ли затронуты обычные члены, что-то вроде:

struct A {
     double a1;
     int b1;
     double a2;
     int b2;
     bool is_assigned[4];
};

или

struct A {
     double a1;
     int b1;
     double a2;
     int b2;
     double* p_a1; // point to a1 when initialized, else nullptr
     int* p_b1;    // point to b1 when initialized, else nullptr
     double* p_a2; // point to a2 when initialized, else nullptr
     int* p_b1;    // point to b2 when initialized, else nullptr
};

struct A {
     double a1;
     int b1;
     double a2;
     int b2;

};

для этого вы можете просто использовать любой тип переменной, чтобы указать, назначены ли две или четыре значения этой переменной.

Как взять переменную name assigned = -1

поэтому, если ваше входное значение положительное, то если два значения находятся внутри файла, просто сделайте

А2 = Б2 = assigend

поэтому, когда вы проверяете, просто проверьте, является ли значение a2 и b2 -1 или что-то еще,