Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何推断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; }; 模板 甲级{ 公众: typedef typename T::标量; }; 模板 结构B:公共A{ 公众: T型标量; };_C++_Templates_Inheritance_Crtp - Fatal编程技术网

如何推断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; }; 模板 甲级{ 公众: typedef typename T::标量; }; 模板 结构B:公共A{ 公众: T型标量; };

如何推断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; }; 模板 甲级{ 公众: typedef typename T::标量; }; 模板 结构B:公共A{ 公众: T型标量; };,c++,templates,inheritance,crtp,C++,Templates,Inheritance,Crtp,但当我看到编译器显示: error: no type named ‘Scalar’ in ‘struct B<int>’ 错误:“结构B”中没有名为“Scalar”的类型 有人能解释一下吗?问题是A的API说必须定义T::Scalar,这在模板结构B:public A{中还不是这样 简单的更改是修复以下API: template <typename SCALAR> class A{ public: typedef SCALAR Scalar; }; templ

但当我看到编译器显示:

error: no type named ‘Scalar’ in ‘struct B<int>’
错误:“结构B”中没有名为“Scalar”的类型

有人能解释一下吗?

问题是
A
的API说必须定义
T::Scalar
,这在
模板结构B:public A{
中还不是这样

简单的更改是修复以下API:

template <typename SCALAR>
class A{
public:
    typedef SCALAR Scalar;
};
template <typename T>
struct B:public A<T> {
};
模板
甲级{
公众:
typedef标量;
};
模板
结构B:公共A{
};
抽象地说,
A,T::Scalar
的使用是按名称传递的一种形式,而
A
是常规的按参数传递。当名称尚未在需要时定义时,按名称传递是有问题的

[编辑] 因为它看起来不明显,所以您仍然可以保留CRTP:

template <typename SCALAR, typename CRTP>
class A{
public:
    typedef SCALAR Scalar;
};
template <typename T>
struct B:public A<T, B<T>> {
};
模板
甲级{
公众:
typedef标量;
};
模板
结构B:公共A{
};

错误是由于类型不完整造成的。请查看下面的行:

template<typename T>
struct B : public A<B<T>> 
模板
结构B:公共A
B
的主体尚未启动,您正在将其用作构建
a
中的参数。实际上这是允许的,但如中所述,这是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;
};
模板
类{//C++11使用``
公众:
T型标量;
//必要时使用'Base'
};
模板
结构B:公共A{
公众://^^^^^^^
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.
调用将调用的
B
B:A将进一步调用//B,但在等待A时尚未完成
{typedef B::Scalar Scalar}将尝试获取尚未像许多人指出的那样构造的B//。
下面的代码不是解决方案,但将解释问题所在。下面的代码编译是因为我们打破了循环

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;
}
模板
甲级{
公众:
typedef typename T::标量;
};
模板
B类:公共A{
公众:
T型标量;
};
模板
甲级{
公众:
typedef int标量;
};
int main()
{
B B;
}

现在的解决办法是打破循环或避免循环。我们可以想出一些相应的解决办法。

,但这个问题更清楚,所以我认为一旦有了答案,我们应该反向重复关闭另一个。@Quentin对此有什么想法吗?链接的问题也适合这个问题(
B
在实例化
A
时不完整),但我觉得在这里复制/修补/粘贴我的答案会很便宜。@Quentin那么,我必须添加一个特征?但是这里
a
根本没有
B
的任何信息。现在
a
怎么能使用
B
的任何方法呢?CRTP不见了!@iammilind:好吧,你可以保留CRTP,并且仍然可以单独通过
SCALAR
这两者并不相互排斥。CRTP只是不需要用于
B::Scalar
。可能您假设,在这种情况下,CRTP仅用于获取
Scalar
;对吗?但如果CRTP和
Scalar
都是出于不同的目的而需要的呢?从Q来看,OP似乎想要CRTP,而在另一方面,他/她却被绊倒了在
Scalar
@iammilind:
T::Scalar
的内部
typedef
不是问题中的内部typedef,它是
a
的按名称传递参数。