C++ 继承类型\u CRTP中派生的特征:派生的类型不完整(尚未完成) 库代码

C++ 继承类型\u CRTP中派生的特征:派生的类型不完整(尚未完成) 库代码,c++,c++14,typetraits,crtp,C++,C++14,Typetraits,Crtp,我的库有一个CRTP类B 我创建了一个Trait类,使用户可以更改B的行为 默认设置为int。(#1) 最后,我创建了一个新类D 我希望D派生C的设置,即std::string(而不是int)。 但是,它不能在$处编译 //D (user2's class) class D : public C<D>{ //#4 public: type f(){return "OK";} //#5

我的库有一个CRTP类
B

我创建了一个
Trait
类,使用户可以更改
B
的行为
默认设置为
int
。(
#1

最后,我创建了一个新类
D

我希望
D
派生
C
的设置,即
std::string
(而不是
int
)。
但是,它不能在
$
处编译

//D (user2's class)
class D : public C<D>{                            //#4
    public: type f(){return "OK";}                //#5
    //$ invalid conversion from 'const char*' to 'B<D>::type {aka int}' 
};
int main(){
    D dt;
    std::cout<< dt.f() <<std::endl;
}
//D(user2的类)
D类:公共C{/#4
public:type f(){return“OK”}/#5
//$从“const char*”到“B::type{aka int}”的转换无效
};
int main(){
D-dt;

std::cout实例化如下:

D -> C<D> -> B<D> -> Traits<D>
然后加上

template<class Derived> class B{
    public: using type = typename Trait<Derived>::type;
    using child = typename getChild<Derived>::child;
    public: type f(){return 1;}
};
模板类B{
public:使用type=typename Trait::type;
使用child=typename getChild::child;
public:type f(){return 1;}
};

B
need
派生类
=派生类最多的子类(
D
,而不是
C
)。此建议可能会破坏我现有的设计。B get被实例化为
B
,因此它同时了解
C
D
。您可以使用另一个帮助器类轻松提取其中一个。在这种特定情况下,它是可以的。但是,另一个用户可以编写
B
。另一个用户可以简单地使用该类执行
B
在这种方法中,我的库需要包含一个模板实用程序来提取最派生的子类(
G
H
)递归。我怀疑它太复杂了,而且不是CRTP直觉。@CPP初学者更新了我的答案,展示了如何获得
G
H
。看到了吗,你走了那么远。谢谢。我仍然觉得这是反CRTP直觉+过度工程。
D -> C<D> -> B<D> -> Traits<D>
template <typename... T>
struct getChild;

template <template <typename... T> typename First, typename... Rest>
struct getChild<First<Rest...>> { using child = typename getChild<Rest...>::child; };

template <typename First>
struct getChild<First> { using child = First; };
template<class Derived> class B{
    public: using type = typename Trait<Derived>::type;
    using child = typename getChild<Derived>::child;
    public: type f(){return 1;}
};