【发布时间】:2012-06-17 08:47:04
【问题描述】:
我有多个类,每个类都有不同的成员变量,这些变量在构造函数中被简单地初始化。这是一个例子:
struct Person
{
Person(const char *name, int age)
:
name(name),
age(age)
{
}
private:
const char *name;
int age;
};
每个都有一个关联的print<>() 函数。
template <>
void print<Person>(const Person &person)
{
std::cout << "name=" << name << "\n";
std::cout << "age=" << age << "\n";
}
此代码容易出错,因为参数列表在四个位置复制。如何重写代码以避免这种重复?我想使用预处理器和/或模板。
例如,我可以使用 X-args 预处理器技术吗?
#define ARGUMENTS \
ARG(const char *, name) \
ARG(int, age)
struct Person
{
Person(LIST_TYPE_NAME_COMMA(ARGUMENTS))
:
LIST_NAME_INIT(ARGUMENTS)
{
}
private:
LIST_TYPE_NAME_SEMICOLON(ARGUMENTS)
};
template <>
void print<Person>(const Person &person)
{
LIST_COUT_LINE(ARGUMENTS)
}
#undef ARGUMENTS
或者更好,基于模板的方法?
请不要质疑我为什么要这样做,有合理的设计决策导致了多个具有命名参数的相似对象。出于性能原因,参数需要命名为成员变量。我只是在探索是否可以只列出一次参数及其类型。
【问题讨论】:
-
你能使用 C++11 的特性吗?因为您可能想查看初始化列表和/或统一初始化;他们可能会帮助您解决这个问题(请参阅:en.wikipedia.org/wiki/…)
-
@AndersK
const char *只是为了示例 -
作为一个对宏重的 C++ 应用程序进行大量维护的人发言......请,请,请不要使用宏编写您自己的语言。与它们一起工作很痛苦,重构很痛苦,新开发人员也很难理解。您不是在示例中编写 C++,而是在编写自己的专有 DSL。当然,这是一种审美/管理观点,而不是纯粹的技术观点。
-
@Rook 我同意您的担忧,并尽可能避免使用宏。我不介意 DSL,因为它使我的
Person-like 类的语法更甜美,这里的目标是消除相同信息容易出错的重复。 -
我觉得最好以某种相对简单的声明方式(也许是 XML)编写类规范,然后使用脚本为您生成样板。这具有使用两种标准语言(C++ 和 XML)的好处,并且 XML/脚本端的丢失、删除或替换不需要使 C++ 无用或无法理解。也许这个解决方案对你来说有点太重了,但你未来的自己会在几年后必须对其进行更改时感谢我;-)
标签: c++ templates arguments c-preprocessor