0

n次元のヒストグラムクラスを書きたいのですが。他のビンなどを含むビンの形式である必要があります。各ビンには最小範囲と最大範囲、および次のディメンションビンへのポインタが含まれます。

ビンは次のように定義されます

template<typename T>
class Bin {
 float minRange, maxRange;
 vector<Bin<either Bin or ObjectType>> bins;
}

この定義は再帰的です。したがって、実行時にユーザーはヒストグラムのディメンションを定義します

so if its just 1-dimension, then
Bin<Obj>
while 3-dimensions
Bin<Bin<Bin<Obj>>>

これは可能ですか?

よろしく

4

2 に答える 2

5

確かに、C++11にはテンプレート用の可変長パラメーターリストがあります。C ++ 11がなくても、すべてのディメンションが同じタイプである場合は、特殊化を使用できます。

template <typename T, unsigned nest>
struct Bin {
  std::vector<Bin<T, (nest-1)> > bins;
};

template <typename T>
struct Bin<T,0> {
  T content;
};

実行時にディメンションを指定できるのは、ある程度までです。固定値でバインドされている場合は、動的でも適切なタイプを選択できます。ただし、多次元のギザギザのベクトルの代わりに1次元のベクトルを使用することを検討してください。

于 2012-06-09T18:39:22.997 に答える
1

提案した正確な構文を取得するには、次のようにします。

template <typename T>
class Bin
{
    float minRange, maxRange;
    std::vector<T> bins;
};

そしてそれはあなたがあなたの質問に入れたものを正確に行うべきです:

Bin< Bin< Bin<Obj> > > bins;

それを動的に(実行時に)行うために、私はいくつかのポリモーフィズムを採用しました。例は少し複雑です。まず、基本タイプがあります。

template <typename T>
class BinNode {
public:
    virtual ~BinNode () {}
    typedef std::shared_ptr< BinNode<T> > Ptr;
    virtual T * is_object () { return 0; }
    virtual const T * is_object () const { return 0; }
    virtual Bin<T> * is_vector() { return 0; }
    const T & operator = (const T &t);
    BinNode<T> & operator[] (unsigned i);
};

BinNodeノードが実際に別のベクトルなのか、それともオブジェクトなのかを判断します。

template <typename T>
class BinObj : public BinNode<T> {
    T obj;
public:
    T * is_object () { return &obj; }
    const T * is_object () const { return &obj; }
};

BinObjから継承しBinNode、オブジェクト自体を表します。

template <typename T>
class Bin : public BinNode<T> {
    typedef typename BinNode<T>::Ptr Ptr;
    typedef std::map<unsigned, std::shared_ptr<BinNode<T> > > Vec;
    const unsigned dimension;
    Vec vec;
public:
    Bin (unsigned d) : dimension(d) {}
    Bin<T> * is_vector() { return this; }
    BinNode<T> & operator[] (unsigned i);
};

BinはのベクトルですBinNode

template <typename T>
inline const T & BinNode<T>::operator = (const T &t) {
    if (!is_object()) throw 0;
    return *is_object() = t;
}

BinNodeそれが実際にオブジェクトである場合、への割り当てを許可します。

template <typename T>
BinNode<T> & BinNode<T>::operator[] (unsigned i) {
    if (!is_vector()) throw 0;
    return (*is_vector())[i];
}

BinNodeベクトルの場合、にインデックスを付けることができます。

template <typename T>
inline BinNode<T> & Bin<T>::operator[] (unsigned i)
{
    if (vec.find(i) != vec.end()) return *vec[i];
    if (dimension > 1) vec[i] = Ptr(new Bin<T>(dimension-1));
    else vec[i] = Ptr(new BinObj<T>);
    return *vec[i];
}

インデックス付けされたアイテムが存在する場合はそれを返します。存在しない場合は、現在のディメンションの深さに応じて適切なエントリを作成します。きれいな印刷のためのリダイレクト演算子の追加:

template <typename T>
std::ostream &
operator << (std::ostream &os, const BinNode<T> &n) {
    if (n.is_object()) return os << *(n.is_object());
    return os << "node:" << &n;
}

Bin次に、次のように使用できます。

int dim = 3;
Bin<float> v(dim);
v[0][1][2] = 3.14;
std::cout << v[0][1][2] << std::endl;

現在、0次元はサポートされていませんが、自分で試してみることをお勧めします。

于 2012-06-09T19:30:04.407 に答える