0

配列を含む抽象基本クラスと、基本クラスに少し大きな配列を持たせたい2つ以上の継承されたクラスがあります。

テンプレートを使用してこれを解決しようとしました:

template <int arraySize>
class Baseclass {
public:
    uint16_t arr[arraySize];
};

class InheritedClass :
    public Baseclass <5> {};

私が今直面している問題は次のとおりです。ある Baseclass-Object へのポインターを使用するたびに、コンパイラーは不平を言います:

クラス テンプレート "Baseclass " の引数リストがありません

ここで何が起こっているのか理解していると思います: テンプレート パラメーターのないベースクラスは完全な型ではありませんが、コンパイラーには完全な型が必要です。

したがって、私は疑問に思います-InheritedClassに配列を割り当ててBaseclassにポインターを渡すことなく、私がやろうとしていることを達成する(より良い)方法はありますか?

前もって感謝します!

4

5 に答える 5

1

Baseclass非テンプレート クラスから派生させ、代わりにそれへのポインターを使用することもできます。

于 2013-10-26T20:07:02.270 に答える
1

おそらく機能するハックとして、baseclassそのreinterpret_casts thisinto にメソッドを含めますbaseclass<1>

これは、ty0es が比較的健全なレイアウトにコンパイルされていることに依存しています。これを促進するにbaseclassは、少なくともポッドまたは標準レイアウトであることを確認してください。

結果は未定義の動作ですが、私が使用したすべてのコンパイラで動作します。

欠点は?並列に転送する必要がある配列の大きさと、実行時の配列サイズについてクラスの他のユーザーに嘘をつきます。さらに、非常に脆弱です。配列は の最後の要素でなければなりませんbaseclass

おそらく、コンパイル時の静的境界を廃止し、実行時の境界で を格納する方がよいでしょう。これにより、std::vector未定義の動作ハックが回避され、コード行ごとの嘘が減ります。

于 2013-10-26T21:18:15.527 に答える
0

引数を明示的に指定すると、C++ は既定の式を無視します。したがって、派生クラスでは、CRTP 'd ベースのニーズを明示的に指定しますが、ベースでは、インスタンス化後に (のみ) 使用されるデフォルト値の計算も提供します。そう:

#include <iostream>
// instantiation specifies size explicitly, default calculation ignored
// after instantiation names in default calculation are bound correctly

template<class d,int size=sizeof d::m2/sizeof *d::m2>
struct b {
        int m[size];
};

struct d: b<d,20> {
        double m2[20];
};

int main() {
        std::cout<<sizeof b<d>::m/sizeof *b<d>::m<<'\n';
}
于 2013-10-26T23:54:58.767 に答える