gpt4 book ai didi

c++ - 类型别名和不完整的类型

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:54:43 24 4
gpt4 key购买 nike

我可能已经超出了解决本应是一个简单问题的范围。我在这里开始这个问题: Getting type of base class at compile time

基本上我试图让类管理它自己的指针类型。我正在包装一个 C 库,其中一些结构中嵌入了引用计数,而另一些则没有。那些没有的,我想使用 shared_ptr。那些这样做,我想使用 intrusive_ptr。我想避免依赖程序员的智慧来确保使用正确的包装器。最终,我想添加更多依赖于此行为的功能,但我还没有做到这一点。

@Yakk 提出了一个使用模板类型别名的有趣解决方案,我已经尝试实现它。不幸的是,我让自己陷入了一个似乎无法解决循环引用以使编译器满意的境地。我收到指向“using pointer=”行的“在嵌套名称说明符中命名的不完整类型‘Test2’”错误。对于 Test::f() 的定义,我还得到一个奇怪的“定义与返回类型中的声明不同”,但我怀疑一旦我解决了第一个错误,它可能会自行解决。

我找到的大多数关于此错误类型的引用资料都涉及头文件的排序,但即使所有内容都在一个文件中,我也无法弄清楚如何排序才能解决此问题。

有什么想法吗?

#include <iostream>
#include <memory>


template<typename T>
class Pointered: public std::enable_shared_from_this<T>
{
public:
using pointer=std::shared_ptr<T>; //<-- incomplete type named error
using weakPointer = std::weak_ptr<T>;
};


template<typename T>
using Ptr = typename T:: pointer;

template<typename T>
using WkPtr = typename T:: weakPointer;


class Test2;

class Test:public Pointered<Test>
{
public:
Ptr<Test2> f();
};


class Test2:public Pointered<Test2>
{
public:
Ptr<Test> p;
Test2(Ptr<Test> ptr):p(ptr){}
};


int main(int argc, const char * argv[])
{
Ptr<Test> p=std::make_shared<Test>();
Ptr<Test> p3=p;
p->f();
std::cout << "Refcount: " << p.use_count() << std::endl;
}


//definition differs from declaration in return type error here
Ptr<Test2> Test::f()
{
return Ptr<Test2>(new Test2((Ptr<Test>)shared_from_this()));
}

最佳答案

您不能转发声明嵌套类型,因为您需要封闭类型的定义,但在您的情况下,您有一个循环依赖性抑制了这一点。

首先要考虑的是循环依赖是否真的是个好主意。在大多数情况下,循环依赖被认为是一种代码味道(表明设计存在问题)。如果你能去掉循环依赖,那么一切都会变得简单。

另一种方法是将对嵌套类型的依赖转移到类型特征上,它可以在类型定义之前在外部定义:

template <typename T>
struct pointer_traits;

template <>
struct pointer_traits<Test1> {
typedef std::shared_ptr<Test1> ptr;
typedef std::shared_ptr<Test1> wptr;
};

通过将依赖移到真实类型之外,您将不再有循环依赖(在语法级别,您仍然应该重新审视设计)。然后,您可以根据需要添加语法糖:

template <typename T>
using ptr = typename pointer_traits<T>::ptr;

class Test1 {
ptr<Test2> p2;
};

如果您真的希望类型也嵌套,您可以使用继承将它们引入作用域,或者以更简单的方式添加适当的 typedef:

class Test1 {
typedef ptr<Test1> ptr_t;
// ...

请注意,这是一个粗略的近似值,如果您选择这种方法,您可以在特征和类型的细节上做一些工作,例如通过添加更多语法糖使其更甜美 ,您可以为 shared_ptr_traitsintrusive_ptr_traits 提供两个特征,并提供单行特征来确定要从中提取 typedef,从而减少特征的定义(每种类型)到一行。

关于c++ - 类型别名和不完整的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17800256/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com