C++ 在类自身的指针上模板化类?
我想在类自己的指针上创建一个模板。我该怎么做呢C++ 在类自身的指针上模板化类?,c++,templates,c++11,circular-dependency,C++,Templates,C++11,Circular Dependency,我想在类自己的指针上创建一个模板。我该怎么做呢 template <typename RefType, typename X> class Foo { public: RefType ptr; X val; }; typedef Foo<Foo*, int> Type1; typedef Foo<std::list<Foo>::iterator itr, int> Type2; 事先不知道x.partner的类型。i、 partner可
template <typename RefType, typename X>
class Foo {
public:
RefType ptr;
X val;
};
typedef Foo<Foo*, int> Type1;
typedef Foo<std::list<Foo>::iterator itr, int> Type2;
事先不知道x.partner的类型。i、 partner可以是标准模板类的指针或迭代器
这是一个非常模糊的用例,我可以不使用它,但是代码看起来会更加优雅。当然这是可能的,但是由于您的类是模板化的,当您在typedef中声明指向它的指针时,您需要选择显式类型:
using Type1 = Foo<Foo<int*, int>*, int>;
并像这样使用它:
Foo<int*, int> myFoo;
int val = 42;
myFoo.ptr = &val;
myFoo.val = 64;
Type1 myObj;
myObj.val = 1337;
myObj.ptr = &myFoo;
Foo<int> first;
first.val = 42;
first.ptr = &first; // now it refers to itself.
std::cout << first.val << std::endl;
// lets go nuts:
std::cout << first.ptr->ptr->ptr->ptr->val << std::endl;
Foo优先;
first.val=42;
first.ptr=&first;//现在它指的是它自己。
std::cout ptr->val您编写的代码无法编译的原因是,如果没有声明之外的模板参数,即使作为指针,Foo也无法运行,例如typedef Foo Type1中的Foo*
代码>
如果按现有方式声明该类,则可以递归地在该typedef中声明Foo
指针,但必须在某个时刻使用非Foo*
RefType才能使其工作。例如:
typedef Foo<Foo<Foo<int*, int>*, int>*, int> Type1;
如果由于某种原因无法更改模板,可以使用void*
并将其重新转换为管件Foo*
:
template<typename RefType, typename X>
class Foo
{
public:
RefType ptr;
X val;
};
typedef Foo<void*, int> Type1;
int main( )
{
Type1 test;
Type1* test2 = static_cast< Type1* >( test.ptr );
}
模板
福班
{
公众:
ref型ptr;
X值;
};
类型def Foo类型1;
int main()
{
1型试验;
Type1*test2=静态投影(test.ptr);
}
然而,这明显更容易出错。使用:
模板
福班
{
公众:
ref型ptr;
X值;
};
模板
福班
{
公众:
使用TypeSelf=Foo;
TypeSelf*ptr;
X值;
};
类型def Foo类型1;
Foo
现在拥有类型为Foo*
的成员ptr
class Base {};
template <typename RefType, typename X>
class Foo : public Base
{
public:
RefType ptr;
X val;
};
typedef Foo<Base*, int> Type1;
int main()
{
Base* p = new Type1;
Type1* pt = static_cast<Type1*>(p);
pt->val = 3;
pt->ptr = new Type1;
(static_cast<Type1*>(pt->ptr))->val = 5;
// delete etc.
return 0;
}
在它的头上旋转的答案:
从Foo派生并使用它而不是typedef,而不是创建基类。这与CRTP类似
struct Type1 : public Foo<Type1 *, int> { };
struct Type2 : public Foo<std::list<Type2>::iterator, int> { };
structType1:publicfoo{};
结构类型2:公共Foo{};
您可以像使用typedef一样使用Type1和Type2。为什么要这样做?Foo
是一种“递归定义”。参数应该是哪种类型的Foo
?相同的?我无法想象这种怪物类型的任何实际用例。如果Foo
是您的模板,那么Foo&
是参考类型。不需要作为参数传递,为什么不能直接使用Foo*ptr代码>在课堂上?这里的问题是,你不能只说Foo*
;在模板化类声明之外,您必须指定您所谈论的Foo
。这是指针指向指针的等价物,因此最终需要指定一个不指向自身的Foo。内部Foo
与外部Foo
@Yakk的类型不同:我不清楚这样的要求。我已编辑我的答案。未编译。在您使用Foo
type.hmm之前,没有Foo
。所以我只需要对指针类型做一个部分专门化,其余的就可以按原样工作了?我喜欢这个答案,因为我不必为每个引用类型写一个部分专门化。但它确实引入了虚拟函数的开销。。。
template<typename X>
class Foo
{
public:
Foo* ptr;
X val;
};
typedef Foo<int> Type1;
template<typename RefType, typename X>
class Foo
{
public:
RefType ptr;
X val;
};
typedef Foo<void*, int> Type1;
int main( )
{
Type1 test;
Type1* test2 = static_cast< Type1* >( test.ptr );
}
template <typename RefType, typename X>
class Foo
{
public:
RefType ptr;
X val;
};
template <typename X>
class Foo<void,X>
{
public:
using TypeSelf = Foo;
TypeSelf* ptr;
X val;
};
typedef Foo<void,int> Type1;
class Base {};
template <typename RefType, typename X>
class Foo : public Base
{
public:
RefType ptr;
X val;
};
typedef Foo<Base*, int> Type1;
int main()
{
Base* p = new Type1;
Type1* pt = static_cast<Type1*>(p);
pt->val = 3;
pt->ptr = new Type1;
(static_cast<Type1*>(pt->ptr))->val = 5;
// delete etc.
return 0;
}
template<typename T>
class Base{
public:
virtual Base<T>*& get_ptr() = 0;
virtual T& get_val() = 0;
};
template <typename RefType, typename X>
class Foo : public Base<X>
{
public:
RefType ptr;
X val;
Base<X>*& get_ptr()
{
return ptr;
}
X& get_val()
{
return val;
};
};
typedef Foo<Base<int>*, int> Type1;
typedef Base<int> BaseType;
int main()
{
BaseType* p = new Type1;
p->get_ptr() = new Type1;
p->get_val() = 5;
// delete etc.
return 0;
}
struct Type1 : public Foo<Type1 *, int> { };
struct Type2 : public Foo<std::list<Type2>::iterator, int> { };