我的图书馆有一个CRTP课程B<Derived>
我创建了一个Trait<T>
类,以便用户更改B
的行为
默认设置为int
。 (#1
)
#include <iostream>
#include <string>
//B and Trait (library class)
template<class Derived> class B;
template<class T>class Trait{
public: using type = int; //<-- default setting //#1
};
template<class Derived> class B{
public: using type = typename Trait<Derived>::type; //#2
public: type f(){return 1;}
};
然后,我使用新设置C
创建一个新课程std::string
。 (#3
)
它工作正常。
//C (user1's class)
template<class Derived> class C ;
template<class Derived>class Trait<C<Derived>>{
public: using type = std::string; //#3
};
template<class Derived> class C : public B<Derived>{};
最后,我创建了一个新课程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;
}
粗略地说,这是我对编译过程的理解: -
class D
(#4
)之前,它并不了解D
。#4
,为了识别D::type
,它会查找C<D>::type
最后,它发现它在B<D>::type
#2
处定义。 #2
开始,转到#1
的定义并找到type
= int
。D::type
= int
。 #3
忽略,因为此时(#4
和#5
),D
仍然不完整。D
派生自C<something>
...... 如何让D
自动从Trait
继承C
的设置而不明确定义另一个模板专精Trait<D>
?
换句话说,#3
如何忽略D
?
Trait
可能不是一个好的设计(?),但我更喜欢让type
设置在一个单独的特质类中。
答案 0 :(得分:1)
实例化如下:
D -> C<D> -> B<D> -> Traits<D>
Traits<D>
与Traits<C<Derived>>
如果您将其更改为template<class Derived> class C : public B<C<Derived>>{};
,而Traits<C<D>>
将实例化std::string
并且与您的专业化相匹配,则会type
为B
。
要从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;}
};
然后加入
npm