库代码
我的图书馆有一个 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;}
};
用户代码 ( full coliru demo )
然后,我创建一个新类 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
设置在一个单独的特征类中。
最佳答案
实例化是这样的:
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
得到 child 你可以使用。
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;}
};
关于c++ - 在 CRTP : type of Derived is not complete (yet) 中继承 Derived 的 type_trait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48161273/