C++:类型别名中的递归依赖关系
C++: recursive dependency in type alias
我想知道以下代码是否正确。它可以在我的计算机上编译和运行,但我觉得ValueClass
中定义的ShowValueClass
类型别名存在递归依赖关系。您能否解释一下编译器如何解决它?
#include <iostream>
namespace tmp {
template <typename T>
struct ShowValueClass {
void ShowValue() { std::cout << T::value << std::endl; }
};
} // namespace tmp
struct ValueClass {
using ShowValueClass = tmp::ShowValueClass<ValueClass>;
static constexpr int value = 42;
};
int main() {
ValueClass::ShowValueClass s;
s.ShowValue();
return 0;
}
这里没有递归。您的类tmp::ShowValueClass<T>
仅适用于具有可由cout
打印的成员value
(具有正确的ostream& operator<<(ostream&, const T&)
定义)T
任何类型的类型。
您在内部添加了一个名为ShowValueClass
的类型别名这一事实ValueClass
引用tmp::ShowValueClass<ValueClass>
没有任何改变。在该上下文中,类的行为就像命名空间一样。
想想如果你从ValueClass
中提取ShowValueClass
会发生什么:
struct ValueClass {
static constexpr int value = 42;
};
using ShowValueClass = tmp::ShowValueClass<ValueClass>;
在这种情况下,您将直接在main()
中访问ShowValueClass
,而不是像您的情况那样以ValueClass::
为前缀。tmp::ShowValueClass
使用T::value
和类型别名ShowValueClass
在ValueClass
中的事实都是无关紧要的(它们没有什么特别之处)。
使用类本身作为模板类的模板参数的整个想法在C++中很普遍。实际上,有一种模式称为CRTP(奇怪的重复模板模式),其中类使用类本身作为参数从模板类继承,例如(来自维基百科):
// The Curiously Recurring Template Pattern (CRTP)
template<class T>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
您可以在此处查看整篇文章:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
一个真正的递归依赖示例
现在,为了完成图片,我可以向您展示一些由于递归定义而无法编译的代码:
template <typename T>
struct A {
static constexpr int val = T::val;
};
struct B {
static constexpr int val = A<B>::val;
};
int main() { }
在这里,A<T>::val
取决于T::val
,这没关系,但B::val
取决于扩展到B::val
A<B>::val
。换句话说,B::val
取决于B::val
,这显然是无法解决的。就像在说:
x := y(x)
y(x)
是:
y(x) := x.
因此,x := x
.显然,无法确定x
的值。
使用模板递归的工作示例
现在,如果递归正确进行并且定义了基本情况,显然它甚至可以用于计算非常复杂的东西。 这里有一个简单的例子:
#include <iostream>
using namespace std;
template <int N>
struct A {
static constexpr int val = N + A<N - 1>::val;
};
template <>
struct A<0> {
static constexpr int val = 0;
};
int main() {
cout << A<10>::val << endl;
}
A<N>::val
递归定义为:
N + A<N-1>::val if N != 0
0 if N == 0
因此,它是从0
到N
(含)的所有数字的总和。
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 如何在C++中递归地按相反顺序打印集合
- 到连接组件算法的问题(递归)
- 同一生成文件中的 make 目标之间的递归依赖关系
- C++:类型别名中的递归依赖关系
- 相互依赖的局部类(或相互递归的lambdas)
- 如何修复/重新设计模板递归依赖项