このようなクラスがあります
struct A {
double a1;
int b1;
double a2;
int b2;
};
a1
、b1
、a2
、およびb2
のファイル値を読み取る必要があります。ほとんどの場合、4つの数値すべてがファイルにありますが、2つの数値しか存在しない場合もあります。
2つの数値がある場合、a1
およびb1
に値を格納し、a2
およびb2
に「何も」格納しないようにします。 a2
とb2
がポインターである場合、それらをnullptr
に割り当てることができますが、それらはポインターではありません。
「何も」保存されていないことを示すために、double
およびint
変数に保存できるものはありますか?
Boost.Optional
が利用可能であることは知っていますが、そのライブラリを避けようとしています。
NANをdouble a2に割り当てると、int b2が無効であることも示されます。
このページ NANの使用。
正当でない値を持っているか、そうでないかのどちらかです。無効な値(-1など)がある場合は、それを番兵として使用します。そうでない場合は、いいえ。 Boost.Optional を使用するか、独自の「値とブール値」クラスをロールします。
できません。私は2つの代替方法を考えることができます:
今後さらに問題が発生するようです。有効な値の数を知る必要性は、コードベースに振りかけられます。
factoryおよびbase classを持つことをお勧めします。基本的に、少なくとも2つのクラスがあります。
struct two_values
{
double a1;
int b1;
};
struct four_values : public two_values
{
double a2;
int b2;
};
関数が明示的に4つの値を必要とする場合、宣言でfour_values
構造を使用します。それ以外の場合は、関数宣言でtwo_values
構造を使用します。
この関係は、four_values
構造を必要とする関数でtwo_values
インスタンスを使用できることを示しています。
代替
別の方法は、アイテムにstd::vector
を使用することです:
struct Container
{
std::vector<double> a_values;
std::vector<int> b_values;
};
このデザインの利点は、6つのアイテムが必要な場合に、ベクターがアイテムの数を教えてくれ、コンセプトが拡張可能であることです。
0
_、_-1
_、std::numeric_limits<int>::max()
など、テキストファイルに含まれない値(不正な値)を選択できます。データを処理するとき、不正な値(またはセンチネル)と等しくない場合にのみ値を使用します。値がいくつあるかを示すブールを含めます。
_struct A {
double a1;
int b1;
double a2;
int b2;
bool has_4_nums;
};
_
ポインター(_int*
_または@Peter Pei Guoによる_std::unique_ptr<int>
_)を使用し、存在しない場合はnullptr
を割り当てます。
boost::optional
を回避するための2つのオプションがあり、Boostへの依存関係があります。
コンパイラの std::experimental::optional
を使用します。これは、GCC 4.9+(および最近のバージョンIIRCのClang)から-std=c++14
で使用できます。
GitHub からのstd::experimental::optional
には、AndrzejKrzemieńskiの「参照実装」を使用します。これはヘッダーのみなので、ヘッダーをプロジェクトにコピーするだけです(もちろん、ライセンスに注意してください)
struct A {
double a1;
int b1;
double a2;
int b2;
};
このため、任意のタイプの変数を使用して、これらの変数に2つまたは4つの値が割り当てられているかどうかを示すことができます。
割り当てられた変数名を取る= -1
入力値が正の場合、2つの値がファイル内にある場合は、
a2 = b2 = assigend
したがって、チェックするときは、a2とb2の値が-1または他の値であるかどうかをチェックするだけです。
または、通常のメンバーが影響を受けているかどうかを知るために、次のような追加のメンバーを追加できます。
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
};