如何使用元组修复多个关联关系?
How to fix multiple association relashionships using a tuple?
我制作了一个简单的系统来处理关联(我制作了一对一关联和一对多关联,但我将在这里重点介绍一对一的情况)。如果一个对象只有一种类型的关联但我需要处理几种类型的关联(即类型 A 的对象 a0 关联到类型 B 的对象 b0 和类型的另一个对象 c0 C)。
我试图通过将关联 class 封装在一个元组中来做到这一点(如果有 better/simpler 方法可以做到这一点,请告诉我)但我现在遇到类型问题。这是我当前的代码(有些模板现在没有使用,比如 ind1,但我以后可能需要它):
template <typename A1, typename A2, size_t ind1, size_t ind2>
class Association
{
public:
virtual ~Association()
{
if (!this->empty())
{
this->clear_associations();
}
}
void associate(A2* ref)
{
if (!this->empty() && _ref == ref)
{
return;
}
if (_ref)
{
std::get<ind2>(*_ref).reset_association();
}
_ref = ref;
std::get<ind2>(*ref).associate(static_cast<A1*>(this));
};
void associate(A2& ref)
{
this->associate(&ref);
};
bool empty() const
{
if (!_ref)
return true;
else
return false;
}
void remove_association(A2* ref)
{
if (_ref == ref)
{
this->reset_association();
std::get<ind2>(ref)->remove_association(static_cast<A1*>(this));
}
}
void remove_association(A2& ref)
{
this->remove_association(&ref);
}
void reset_association()
{
_ref = 0;
}
void clear_associations()
{
if (_ref)
{
std::get<ind2>(_ref)->remove_association(static_cast<A1*>(this));
}
this->reset_association();
}
A2* get_association() const
{
return _ref;
}
private:
A2* _ref=0;
};
template <typename... T>
class Relations : public std::tuple<T...>
{
public:
Relations();
virtual ~Relations();
};
class J;
class K;
class I : public Relations<Association<I, J, 0, 0>, Association<I, K, 1, 0>>
{
public:
std::string type="I";
};
class J : public Relations<Association<J, I, 0, 0>>
{
public:
std::string type="J";
};
class K : public Relations<Association<K, I, 0, 1>>
{
public:
std::string type="K";
};
int main()
{
I i;
J j;
K k;
std::get<0>(i).associate(j);
return 0;
}
这里的问题是当我尝试做 std::get(*ref).associate(static_cast(this)); A1 是 I 类型,而 this 是 Association 类型,由于元组的原因不能直接转换。请问有什么好的方法吗?
您可以为 Relation
创建自己的 get:
namespace std
{
template <std::size_t I, typename... Ts>
auto get(Relations<Ts...>& r)
-> typename std::tuple_element<I, std::tuple<Ts...>>::type&
{
return static_cast<typename std::tuple_element<I, std::tuple<Ts...>>::type&>(r);
}
}
我制作了一个简单的系统来处理关联(我制作了一对一关联和一对多关联,但我将在这里重点介绍一对一的情况)。如果一个对象只有一种类型的关联但我需要处理几种类型的关联(即类型 A 的对象 a0 关联到类型 B 的对象 b0 和类型的另一个对象 c0 C)。 我试图通过将关联 class 封装在一个元组中来做到这一点(如果有 better/simpler 方法可以做到这一点,请告诉我)但我现在遇到类型问题。这是我当前的代码(有些模板现在没有使用,比如 ind1,但我以后可能需要它):
template <typename A1, typename A2, size_t ind1, size_t ind2>
class Association
{
public:
virtual ~Association()
{
if (!this->empty())
{
this->clear_associations();
}
}
void associate(A2* ref)
{
if (!this->empty() && _ref == ref)
{
return;
}
if (_ref)
{
std::get<ind2>(*_ref).reset_association();
}
_ref = ref;
std::get<ind2>(*ref).associate(static_cast<A1*>(this));
};
void associate(A2& ref)
{
this->associate(&ref);
};
bool empty() const
{
if (!_ref)
return true;
else
return false;
}
void remove_association(A2* ref)
{
if (_ref == ref)
{
this->reset_association();
std::get<ind2>(ref)->remove_association(static_cast<A1*>(this));
}
}
void remove_association(A2& ref)
{
this->remove_association(&ref);
}
void reset_association()
{
_ref = 0;
}
void clear_associations()
{
if (_ref)
{
std::get<ind2>(_ref)->remove_association(static_cast<A1*>(this));
}
this->reset_association();
}
A2* get_association() const
{
return _ref;
}
private:
A2* _ref=0;
};
template <typename... T>
class Relations : public std::tuple<T...>
{
public:
Relations();
virtual ~Relations();
};
class J;
class K;
class I : public Relations<Association<I, J, 0, 0>, Association<I, K, 1, 0>>
{
public:
std::string type="I";
};
class J : public Relations<Association<J, I, 0, 0>>
{
public:
std::string type="J";
};
class K : public Relations<Association<K, I, 0, 1>>
{
public:
std::string type="K";
};
int main()
{
I i;
J j;
K k;
std::get<0>(i).associate(j);
return 0;
}
这里的问题是当我尝试做 std::get(*ref).associate(static_cast(this)); A1 是 I 类型,而 this 是 Association 类型,由于元组的原因不能直接转换。请问有什么好的方法吗?
您可以为 Relation
创建自己的 get:
namespace std
{
template <std::size_t I, typename... Ts>
auto get(Relations<Ts...>& r)
-> typename std::tuple_element<I, std::tuple<Ts...>>::type&
{
return static_cast<typename std::tuple_element<I, std::tuple<Ts...>>::type&>(r);
}
}