如何在 CRTP 中推断类型
How to infer the type in CRTP?
我想在 c++ 模板中实现 CRTP。代码如下:
template <typename T>
class A{
public:
typedef typename T::Scalar Scalar;
};
template <typename T>
struct B:public A<B<T> > {
public:
typedef T Scalar;
};
但是当我编译代码时,编译器显示:
error: no type named ‘Scalar’ in ‘struct B<int>’
谁能解释一下?
该错误是由于类型不完整造成的。请看下面的行:
template<typename T>
struct B : public A<B<T>>
B<T>
的主体尚未开始,您正在将其用作构建A<T>
的参数。实际上这是允许的,但正如昆汀的回答中提到的,这是CRTP的一个警告。除了这个答案,这里有另一种方式:
template <template<typename> class Base, typename T>
class A{ // use `<typename...>` for C++11
public:
typedef T Scalar;
// use `Base<T>` wherever required
};
template <typename T>
struct B : public A<B, T> {
public: // ^^^^^^^
typedef T Scalar;
};
问题是A<T>
的 API 说必须定义T::Scalar
,这在template<typename U> struct B:public A<B<U> > {
中还不是这样。
简单的更改是修复 A 的 API:
template <typename SCALAR>
class A{
public:
typedef SCALAR Scalar;
};
template <typename T>
struct B:public A<T> {
};
抽象地说,A<T>, T::Scalar
的使用是一种按名称传递的形式,而A<SCALAR>
是常规的按参数传递。当名称尚未在您需要它们的位置定义时,按名称传递是有问题的。
[编辑]而且因为它看起来并不明显,所以您仍然可以保留 CRTP:
template <typename SCALAR, typename CRTP>
class A{
public:
typedef SCALAR Scalar;
};
template <typename T>
struct B:public A<T, B<T>> {
};
另一种看待它的方式,
B<int> b is called which will invoke
B<int> : A<B<int> > which will further invoke // B is not yet done waiting on A<B<int> >
A<B<int>> { typedef B<int>::Scalar Scalar } will try to fetch B<int> //which is not yet constructed as many pointed out.
下面的代码不是解决方案,但会解释问题所在。下面的代码编译是因为我们打破了循环。
template <typename T>
class A{
public:
typedef typename T::Scalar Scalar;
};
template <typename T>
class B:public A<B<T> > {
public:
typedef T Scalar;
};
template <>
class A<B<int> > {
public :
typedef int Scalar;
};
int main()
{
B<int> b;
}
现在的解决方案是打破循环或避免循环。因此,我们可以想到很少的解决方案。
相关文章:
- CRTP 单一实例不完整类型或非文本类型
- c++ 使用 CRTP 为变量模板中的每个类型创建纯虚拟重载
- CRTP:为什么获得嵌套类型和派生类的嵌套方法有区别
- 从具有泛型返回类型的 crtp 基类调用派生类中的函数
- CRTP:如何推断要用作返回类型的成员类型?
- CRTP - 嵌套叶类类型的可见性
- std::d eclval vs crtp,无法从不完整类型推断方法返回类型
- CRTP 模式 但是在数据结构中存储非同构类型
- 在执行 SFINAE 时访问模板派生类 (CRTP) 的静态函数时类型不完整
- 类型特征检查 CRTP 派生,在基类中,问题是未定义的类型
- 懒惰依赖性类型(CRTP)
- 使用派生的模板参数类型作为函数 (CRTP) 的返回类型
- clang vs gcc CRTP:constexpr 变量不能有非文字类型
- 带有CRTP可克隆类的无效协变量类型
- 不知道派生类型的静态CRTP类
- 在模板化类型的CRTP中定义类型
- C++泛型编程 CRTP 基类继承自派生类型提供的类
- CRTP -- 访问不完整的类型成员
- 推断CRTP中模板化成员函数的返回类型
- CRTP和基类定义的类型的可见性