【发布时间】:2021-12-28 12:01:11
【问题描述】:
假设一个类有两个不同的类,但它们的目的有些“等价”,所以它们有相同的成员,一个可以被另一个分配:
struct Pure
{
QString name;
int age = 18;
};
struct Observable
{
QProperty<QString> name;
QProperty<int> age {18};
void operator=(const Pure& other)
{
name = other.name;
age = other.age;
}
};
QProperty 是一个template class from Qt,但我认为这个问题与 Qt 无关,因为它适用于与 T 进行转换/分配的任何其他 template <typename T> class Foo。
问题是如何避免重复,所以不能轻易地从一个类中添加或删除成员而忘记在另一个类中执行此操作,同时仍然保留将一个类的对象分配给另一个类的可能性。
我用模板尝试了几件事,这似乎是最有希望的:
// Adding two helpers only available in C++ 20 for convenience.
template<typename T>
struct type_identity { using type = T; };
template<typename T>
using type_identity_t = typename type_identity<T>::type;
template<template<typename T> typename T>
struct State
{
T<QString> name;
T<int> age;
// std::enable_if_t<std::is_same<QProperty<class X>, T>>
// operator=(const State<type_identity_t>& other)
// {
// name = other.name;
// age = other.age;
// }
};
int main()
{
State<type_identity_t> state;
state.age = 42;
State<QProperty> observableState;
observableState = state; // Desired use. Fails to compile without operator=
}
注释掉的代码无法编译(错误:使用模板模板参数'T'需要模板参数),错误在第一条注释行末尾的T,但我不知道如何解决这个问题。
【问题讨论】:
-
C++ 不能解决所有问题。以某种结构化格式(如 XML 或 YAML)在单独的文件中列出所有类成员及其类型,并编写一个简单的脚本来为这两个类生成 C++ 代码。将其集成到您的构建系统中。
-
我知道这是一种可能。我经常使用代码生成,因为它在 Qt 中很常见,或者当您需要 IPC/RPC 等时。但是,您认为使用模板是不可能的吗?
-
第一步半自动进行(目前还没有检查):Pure 可以静态检查 Observable 是否定义了两个成员。 Observable 在赋值运算符中间接检查它。
-
C++ 的当前状态不允许这样的东西完全在 C++ 本身中实现。
-
谢谢,我知道基于元类提案的解决方案将节省所有样板文件。但我只是决定在
operator=上拥有一个模板和only 的副本。