gpt4 book ai didi

c++ - 在 CRTP : type of Derived is not complete (yet) 中继承 Derived 的 type_trait

转载 作者:行者123 更新时间:2023-11-30 05:05:53 28 4
gpt4 key购买 nike

库代码

我的图书馆有一个 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> ... 然而。

enter image description here

问题

如何让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/

28 4 0