4

次の構文はOpenCVで機能しています

Mat R = (Mat_<double>(4, 4) <<
        1,          0,           0, 0,
        0, cos(alpha), -sin(alpha), 0,
        0, sin(alpha),  cos(alpha), 0,
        0,          0,           0, 1);

それはどのようにできますか?オーバーロードされた演算子は? この表現の意味は何ですか?最近ではコンマ演算子をオーバーロードできますC++か?

4

3 に答える 3

4

コンマ演算子はオーバーロードできますが、通常は推奨されません (多くの場合、オーバーロードされたコンマは混乱を招きます)。

上記の式は、4*4 マトリックスの 16 個の値を定義します。これがどのように可能か疑問に思われる場合は、より簡単な例を示します。次のようなものを書きたいとします。

MyVector<double> R = (MyVector<double>() << 1 , 2 , 3);

<<次に、 and,演算子が新しい値をベクターに追加するように MyVector を定義できます。

template<typename T> 
class MyVector: public std::vector<T> {
 public:
  MyVector<T>& operator << (T value) { push_back(value); return *this; }
  MyVector<T>& operator , (T value) { push_back(value); return *this; }
  ...
};
于 2013-06-12T21:17:23.973 に答える
3

が使用されていることがわかるように、here から取得した実際のコードを次に示します。operator,

template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
MatCommaInitializer_<_Tp>::operator , (T2 v)
{
     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
     *this->it = _Tp(v); ++this->it;
    return *this;
}

次の値を取り、単純に行列に入れ、反復子をインクリメントしてから、MatCommaInitializerオブジェクトへの参照を返します (これらの演算子を連結できるようにするため)。

于 2013-06-12T21:28:34.653 に答える
2

以下はOpenCVのソースコードです。クラス MatCommaInitializer_ が,演算子をオーバーロード<<し、グローバル静的フィールドで演算子をオーバーロードしたことがわかります。

`
core.hpp
...
template<typename _Tp> class MatCommaInitializer_
{
public:
    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
    MatCommaInitializer_(Mat_<_Tp>* _m);
    //! the operator that takes the next value and put it to the matrix
    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
    //! another form of conversion operator
    Mat_<_Tp> operator *() const;
    operator Mat_<_Tp>() const;
protected:
    MatIterator_<_Tp> it;
};
...
`

`
mat.hpp
...
template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
operator << (const Mat_<_Tp>& m, T2 val)
{
    MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
    return (commaInitializer, val);
}
...
`

したがって、コードの作業プロセスは次のとおりです。

  1. Mat_(4, 4) は、4 行 4 列の double 型の要素を含むインスタンスを作成します。

  2. 次に、オーバーロードされた<<演算子を呼び出し、MatCommaInitializer_ インスタンスを返します。

  3. 次に、オーバーロードされた,演算子を呼び出し、MatCommaInitializer_ インスタンスなどを返します。

  4. 最後にコンストラクタを呼び出しますMat(const MatCommaInitializer_<_Tp>& commaInitializer)

于 2015-12-15T04:51:09.240 に答える