19

Eigen ライブラリのドキュメントを読んで、一部のオブジェクトは値渡しできないことに気付きました。そのようなオブジェクトを安全に値渡しできるようにする C++11 の開発または計画された開発はありますか?

また、そのようなオブジェクトを値で返すことに問題がないのはなぜですか?

4

2 に答える 2

19

Eigen がひどく書かれたライブラリである (または単によく考えられていない) 可能性は十分にあります。何かがオンラインだからといって、それが真実であるとは限りません。例えば:

オブジェクトを値で渡すことは、ほとんどの場合、C++ では非常に悪い考えです。これは、役に立たないコピーを意味し、代わりに参照で渡す必要があるためです。

オブジェクトによっては、これは一般的に良いアドバイスではありません。C++11 より前のバージョンでは (オブジェクトをコピー不可にする場合があるため) 必要になる場合がありますが、C++11 では必要ありません。それでもそうするかもしれませんが、常に参照によって値を渡す必要はありません。割り当てられたメモリなどが含まれている場合は、値で移動できます。明らかに、それが「見るが触れない」ようなものであれば問題ありませんconst&

おそらくEigenのもののような単純な構造体オブジェクトは、おそらくVector2dコピーするのに十分安価であり(特にポインターが64ビットであるx86-64では)、コピーはパフォーマンスの点であまり意味がありません。同時に、(理論的に) オーバーヘッドであるため、パフォーマンスが重要なコードを使用している場合は、役立つ場合があります。

繰り返しますが、そうではないかもしれません。

Eigen が話していると思われる特定のクラッシュの問題は、オブジェクトの配置に関係しています。ただし、ほとんどの C++03 コンパイラ固有のアラインメント サポートでは、すべてのケースでアラインメントが保証されています。したがって、「プログラムがクラッシュする!」という理由はありません。値パラメータでクラッシュを引き起こすコンパイラ固有のアラインメント宣言を使用する SSE/AltaVec/etc ベースのライブラリを見たことがありません。そして、私はかなりの数を使用しました。

したがって、彼らがこれになんらかのクラッシュの問題を抱えている場合、Eigen は...疑わしいメリットがあると考えます。さらなる調査なしではありません。

また、Eigen ドキュメントが示唆するように、オブジェクトが値渡しに安全でない場合、これを処理する適切な方法は、オブジェクトをコピー構築不可能にすることです。既存のオブジェクトが必要なため、コピー割り当ては問題ありません。ただし、Eigen はこれを行っていません。これは、開発者が API 設計の細かい点のいくつかを見逃していることを再度示唆しています。

ただし、記録のために、C++ 11 にはalignasキーワードがあります。これは、オブジェクトが特定の配置であることを宣言する標準的な方法です。

また、そのようなオブジェクトを値で返すことに問題がないのはなぜですか?

存在しないと誰が言いますか (配置の問題ではなく、コピーの問題に注意してください)。違いは、参照によって一時的な値を返すことができないことです。それは不可能なので、彼らはそれをしていません。

于 2012-04-04T21:22:16.243 に答える
11

彼らは C++11 でこれを行うことができます:

class alignas(16) Matrix4f
{
    // ...
};

これで、クラスは常に 16 バイト境界に整列されます。

また、私はばかげているかもしれませんが、とにかくこれは問題ではありません。次のようなクラスがあるとします。

class Matrix4f
{
public:
    // ...
private:
    // their data type (aligned however they decided in that library):
    aligned_data_type data;

    // or in C++11
    alignas(16) float data[16];
};

Matrix4fいずれにせよ、コンパイラは 16 バイト境界にを割り当てる義務があります。クラスレベルalignasは冗長でなければなりません。しかし、どういうわけか、私は過去に間違っていることが知られていました。

于 2012-04-04T21:23:38.477 に答える