[解決済み] 便利なVector3fクラス
質問
を持つ必要がある場合があります。
Vector3f
クラスがあり、そのクラスは
x
,
y
と
z
のメンバーとしてインデックス化することができます。
float[3]
の配列を同時に作成することができます(これについては、すでにこのSOでいくつかの質問があります)。
のようなものです。
struct Vector3f {
float data[3];
float &x = data[0];
float &y = data[1];
float &z = data[2];
};
これを使えば、こう書ける。
Vector3f v;
v.x = 2.0f;
v.y = 3.0f;
v.z = 4.0f;
glVertex3fv(v.data);
しかし、この実装では、参照が
struct
(これは非常に残念なことです。この特別なケースで参照を削除できない理由は見当たりません。おそらく、コンパイラ側の最適化ミスでしょう)。
しかし
[[no_unique_address]]
こんなアイデアもありました。
#include <new>
template <int INDEX>
class Vector3fProperty {
public:
operator float() const {
return propertyValue();
}
float &operator=(float value) {
float &v = propertyValue();
v = value;
return v;
}
private:
float &propertyValue() {
return std::launder(reinterpret_cast<float*>(this))[INDEX];
}
float propertyValue() const {
return std::launder(reinterpret_cast<const float*>(this))[INDEX];
}
};
struct Vector3f {
[[no_unique_address]]
Vector3fProperty<0> x;
[[no_unique_address]]
Vector3fProperty<1> y;
[[no_unique_address]]
Vector3fProperty<2> z;
float data[3];
};
static_assert(sizeof(Vector3f)==12);
つまり、基本的には、プロパティに
struct
へのアクセスを処理します。
x
,
y
と
z
. これらのプロパティは、空であるためスペースを取らないようにする必要があり、その属性は
[[no_unique_address]]
この方法についてどう思われますか?UBがあるのでしょうか?
なお、この質問は、これらすべてが可能なクラスについてのものです。
Vector3f v;
v.x = 1;
float tmp = v.x;
float *c = v.<something>; // there, c points to a float[3] array
解決方法は?
<ブロッククオートしかし、この実装は、参照が構造体のスペースを取るので、まずいです(これは非常に残念なことです。この特殊なケースで参照を削除できない理由は見当たりませんが、もしかしたらコンパイラ側の最適化ミスかもしれません)。
これは複雑な問題のようですね。標準レイアウトのクラスは、互いに互換性がなければなりません。そのため、コンパイラは、どのように定義されているかにかかわらず、メンバーを排除することはできません。非標準レイアウトの場合は?それはわからない。詳しくは、これを読んでください。 C++標準は、未使用のプライベートフィールドがsizeofに影響を与えることを保証していますか?
私の経験では、コンパイラはクラスのメンバを、たとえ "unused"であっても削除しません(たとえば、形式的には
sizeof
はそれらを使用しています)。
UBは搭載されていますか?
これはUBだと思います。まず第一に
[[no_unique_address]]
は、そのメンバーが
は必要ありません。
は一意なアドレスを持つのであって
はしてはならない
は一意なアドレスを持っています。次に、あなたの
data
メンバが始まります。ここでも、コンパイラは、以前の
[[no_unique_address]]
クラスのメンバーです。つまり、不正確なメモリにアクセスする可能性があるということです。
もう一つの問題は、"inner" クラスから "outer" メモリにアクセスしたいことです。このようなことは、C++ではUBである。
<ブロッククオートこの方法についてどう思われますか?
それが正しいとして(正しくないが)、私はまだそれが好きではありません。あなたはゲッター/セッターが欲しいのでしょうが、C++はこの機能をサポートしていません。だから、そのような奇妙で複雑な構造をする代わりに(このコードを他の人がメンテナンスすることを想像してください)、単純に次のようにするのはどうでしょう。
struct Vector3f {
float data[3];
float x() {
return data[0];
}
void x(float value) {
data[0] = value;
}
...
};
あなたはこのコードが醜いと言っています。そうかもしれません。しかし、シンプルで、読みやすく、メンテナンスしやすいコードです。UBもないし、ユニオンを使ったハックの可能性にも依存しないし、美の追求を除けば、まさにあなたが望むことをやってくれるんです :)
関連
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] C++でクラスと構造体はいつ使い分けるべきか?
-
[解決済み] 派生クラス関数から親クラス関数を呼び出すには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】C++の余分な資格エラー
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】デバッグアサーションに失敗しました