模板参数中的自引用模板 [英] Self-referencing Template in Template Argument

查看:25
本文介绍了模板参数中的自引用模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我该怎么做才能完成这项工作:

What can I do to make this work:

template<class C, class V, Test V::*>
class Test {
};

它给了我编译器错误:

unknown type name 'Test'

目前这是一个自引用模板,这似乎是不可能的.怎么做才能让它发挥作用?

It's a self-referencing template for now, which doesn't seem possible. What could possibly be done to make it work?

这就是我需要的.我想以最少的编码工作实现双向(想想父子)关系模式.

Here's what I'd need this for. I want to implement a bi-directional (think parent-child) relationship schema with the least minimum coding effort.

template <class O, class T, Reference<T, O, Reference O::*> T::* opposite>
class Reference
{
    T **data;
    int count;
public:
    Reference(): data(new T*[N]), count(0) {}
    ~Reference() {delete[] data;}
    Reference &add(T *t) {
        handleOtherSide();
        return link(t);
    }
    // a lot of stuff to implement this
};

那是集合类.使用方法如下:

That's the collection class. Here's how it would be used:

class Partner
{
public:
    Reference<Partner, Address, &Address::partner> addresses;
};

class Address
{
public:
    Reference<Address, Partner, &Partner::addresses> partner;
};

我的目标是将 Reference 工作所需的一切都作为模板参数提供,这样就不需要为 Partner 和 Address 等类提供构造函数(目前我提供相反的成员指针作为构造函数 arg,但这需要我有参与者类的显式构造函数).我还需要传入或计算一个指向 Reference 类的所有者"指针.我在这里忽略了这个问题,因为我想专注于自引用模板方面.

My goal is to have everything necessary for Reference to work be supplied as template argument, so that there is no need to provide constructors for classes like Partner and Address (currently I supply the opposite member pointer as a constructor arg but this requires me to have explicit constructors for the participant classes). I would also need to pass in or calculate an "owner" pointer to the Reference class. I left this problem out here because I want to focus on the self-referencing template aspect.

想到这一点最简单的方法是 boost::bimap.但是 bimap 的问题是我不想要封闭的 bimap 而只是它的左右部分.bimap 也不可行,因为它会导致一个单一的 bimap 管理特定关系的所有关联.它可能会持有大量对象,从而减慢对其的操作.

The easiest way to think of this is boost::bimap. But the problem with bimap is that I don't want the enclosing bimap but just the left and right part of it. bimap is also not feasible because it would lead to one single bimap managing all associations of a specific relationship. It would possibly hold a large number of objects slowing down operations on it.

推荐答案

问题是,我想要实现的在 C++ 中是不可能的,至少用模板和我瞄准的代码和类的数量是不可能的(阅读:每个成员一行代码).它从需要前向声明和完全定义类型的编译器开始,这使得按值成员和模板参数不可能实现(在循环依赖的情况下).然后,当该成员的类尚未完全定义时,不可能将成员指针作为模板 arg.这一切的根本原因是编译器的工作方式:它是单次传递.我对此无能为力.

The problem is, what I want to achieve is not possible in C++, at least not with templates and the amount of code and classes I am aiming at (read: single line of code per member). It starts with the compiler needing forward declarations and fully defined types, which is making by-value members and template arguments of such impossible (in case of cyclic dependencies). Then it is not possible to have a member pointer as a template arg when the class of that member is not yet fully defined. The root cause of all this is how the compiler works: it is single pass. And there is nothing I can do about that.

解决方案是使用按引用成员或 OO 样式基类或 boost::any 样式容器来避免模板.对于后 2 个,可能有按值成员.

The solution is to use by-reference members or an OO style base class or a boost::any style container to avoid the templates. With the latter 2 it might be possible to have by-value members.

这篇关于模板参数中的自引用模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆