基本CRTPクラスのリーフCRTPクラスのネストされたクラスを使用できるかどうかを理解したいと思います。以下の例は、この問題を示しています。CRTP - ネストされたリーフクラスのタイプの可視性
#include <iostream>
using namespace std;
template<class T>
class A
{
protected:
T* asLeaf(void)
{return static_cast<T*>(this);}
T const* asLeaf(void) const
{return static_cast<T const*>(this);}
public:
struct Inner
{int a = 10;};
void dispInner(void) const
{std::cout << asLeaf()->inner.a << std::endl;}
// I would like to use T::Inner in this class, e.g.
// typename T::Inner mvInnerA;
// However, I understand that it is not possible to
// use it in the form that is stated above. Thus,
// I am looking for any possible workarounds.
};
class B: public A<B>
{
public:
struct Inner: public A<B>::Inner
{int b = 20;};
protected:
friend A<B>;
B::Inner inner;
public:
void dispInner(void) const
{
A<B>::dispInner();
std::cout << asLeaf()->inner.b << std::endl;
}
};
int main()
{
B b;
b.dispInner();
return 0;
}
EDIT
私が受け取ったフィードバックに基づいて、いくつかの更なるコメントを提供したいと思います:
- 私は、適切な設計手法を使用していないことを承知しています。特に、
A
がinner
の存在を意識しているべきかどうかが疑問視されるかもしれません。しかし、inner
のタイプをB::Inner
と定義し、inner
の定義をB
に指定し、A
に使用する代わりにA
に定義したいと思います。 - 私は
B
および/またはB::Inner
と宣言することができず、これを行うことができない理由については知らせています。したがって、技術的には、設計上の問題には解決策がありません。しかし、私は実行可能な回避策を探しています。可能な実現可能な解決策の一つはA
でB::Inner inner
「を定義」とその機能を提供するA
のメンバ関数を使用する試みを作ることではありません- :私はすでにいくつかの代替ソリューションを検討している
A<B>::Inner
の部分をB::Inner inner
に変更することができます。 - もう1つの解決策は、クラス
A<B>::Inner
とB::Inner
を明示的に(すなわちネストされたクラスとしてではなく)定義することです。しかし、私は、設計によって、A
から派生していない任意のクラスがA<B>::Inner
と対話する必要があることを期待するかしないので、これを避けることを好むだろうA<B>::Inner
どちらのソリューションから派生するクラスそのI提示されたものが受け入れられるかもしれない。しかし、私は実現可能な選択肢を探しています。
一般的なルールは、あなたのBaseクラスがその子について知ってはならないということです.CRC(https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)を使用しているのはなぜですか? – lapinozz
@lapinozzです。それには何も間違っていません。 –
@lapinozz - 動的多型の考え方は、CRTPの静的多型に完全に直交しています。同じ「ルール」が必ずしも適用されるわけではありません。 – StoryTeller