C++泛型编程 CRTP 基类继承自派生类型提供的类
C++ generic programming CRTP base class inherit from class provided by derived type
浏览Stroustrup的"C++编程语言",第4版。27.4.1 组合数据结构中有一些我无法弄清楚的示例代码。使用派生类 (CRTP 模式) 通过模板参数提供的基类中的类型别名时会出现此问题。
1 #include <vector>
2 using namespace std;
3 struct Red_black_balance {};
4 template<typename N>
5 struct Node_base : N::balance_type { //<==
6 N* left_child;
7 N* right_child;
8 Node_base() { }
9 };
10 template<typename Val, typename Balance>
11 struct Search_node : Node_base<Search_node<Val, Balance>>
12 {
13 using balance_type = Balance; // <==
14 Val val;
15 Search_node(Val v): val(v) {}
16 };
17 template<typename T>
18 using Rb_node = Search_node<T, Red_black_balance>;
19 using My_node = Rb_node<double>;
20 int main(int, char **)
21 {
22 My_node my_root(0.0);
23 return 0;
24 }
下面是编译器输出(g++ 版本 4.9.2):
$ g++ -std=c++11 -Wall -pedantic -o test15 test15.cpp
test15.cpp: In instantiation of ‘struct Node_base<Search_node<double, Red_black_balance> >’:
test15.cpp:11:8: required from ‘struct Search_node<double, Red_black_balance>’
test15.cpp:22:17: required from here
test15.cpp:5:8: error: no type named ‘balance_type’ in ‘struct Search_node<double, Red_black_balance>’
struct Node_base : N::balance_type {
^
据我了解,当模板实例化在main()中完成时,所有模板依赖类型都应根据该点的信息生成(与在模板定义点实例化的非依赖类型不同)。所以编译器在 main 中生成 Node_base 实例时应该知道 N::balance_type 对应于什么,对吧?但似乎并非如此。知道代码中出了什么问题吗?
这实际上是一个循环依赖问题。
template<typename N>
struct Node_base : N::balance_type
为了实例化Node_base<N>
,我们需要先看看N::balance_type
。
template<typename Val, typename Balance>
struct Search_node : Node_base<Search_node<Val, Balance>>
为了实例化Search_node<Val, Balance>
,我们需要先实例化Node_base<Search_node<Val, Balance>>
。这需要实例化Search_node<Val, Balance>::balance_type
,这需要实例化Search_node<Val, Balance>
。
您可以单独传递Balance
:
template <typename Derived, typename Balance>
struct Node_base : Balance { .. };
template <typename Val, typename Balance>
struct Search_node : Node_base<Search_node<Val, Balance>, Balance> { .. };
相关文章:
- 存储模板类型以强制转换回派生<T>
- 在 C++ 中用派生类型重写成员函数
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 在 C++ 中将对象转换为派生类型
- 如何检查派生类的类型?(C++实例)
- 创建派生自可变参数模板包的类型元组
- C++如果采用类类型的函数被传递派生类型,有没有办法给出错误?
- 返回派生类型时出现协变类型错误
- 静态自动 constexpr t = { "red" , "black" , "green" } 是什么类型;派生到?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- (C++);动态决定函数的类型(派生类)
- 如何使variadic模板类方法以函数指针为参数,类型派生自函数模板
- 如何防止从 c++03 中的类型派生
- 如何为从特定类型派生的类型专门化模板
- 为什么在返回从函数的返回类型派生的类型本地对象时不选择 move 构造函数?
- 如何在模板类型中强制静态成员初始化?或如何获取从模板类型派生的所有类的计数
- 有没有任何方法可以从C++中的成员指针类型派生对象类型
- 在c++中基于另一个变量类型派生一个变量类型