【发布时间】:2019-10-23 17:00:42
【问题描述】:
编辑:
- 我想实现一个主题 - 观察者模式,这样我就可以从任何地方调用
notify<SUBJECT>()并且调用许多update<SUBJECT>()函数 - 主题是结构类型。可以有几个这样的主题
- 我希望能够将观察者更新函数放在代码中的任何位置(在不同的编译单元中)
- notify 函数需要知道在编译时要调用哪些更新函数
- 如果通知功能可以自动连接到更新功能就好了
我正在尝试实现一种观察者模式,即通知机制。我目前使用一种运行时实现,它允许将自身附加到向量。但是,所有“附加”调用都是在启动期间进行的,因此也可以在编译时完成(我希望完成)。
- 我的第一个想法是没有 int 模板参数,这会导致链接器重新定义错误。如果您可以告诉链接器保留所有它们并调用它们,那就太好了,但我很确定这是做不到的。
- 现在我使用弱链接和一个 int 模板参数来使方法独一无二。然而,这并不像我想要的那样舒服。必须记住整个代码库中的所有数字。至少,当我使用该数字两次时,我会遇到严重错误。
- 我对模板元编程不是很深入,但我认为当涉及到不同的编译单元时它会变得复杂(但我也可以切换到单个编译单元)
- 我想避免使用 boost,但 C++17 完全没问题。
这是常见的标题:
struct Test {
int value;
};
namespace Observer
{
template<typename T, int N>
void update(decltype(T::value));
/*
* This ìs a function dummy which can be overloaded with the
* real implementation. The linker overrides them and kicks out
* the unoverridden functions since they do nothing.
*/
template<typename T, int N>
void __attribute__((weak)) update(decltype(T::value)) {}
}
template<typename T>
void notify(decltype(T::value) value)
{
Observer::update<T, 1>(value, value != old);
Observer::update<T, 2>(value, value != old);
Observer::update<T, 3>(value, value != old);
}
假设我们有两个编译单元:
template<>
void Observer::update<Test, 1>(decltype(Test::value) value)
{
std::cout << "update: " << value << std::endl;
}
template<>
void Observer::update<Test, 2>(decltype(Test::value) value)
{
std::cout << "update: " << value << std::endl;
}
我需要摆脱不同编译单元中的数字迭代,但仍然可以有多个相同类型的更新函数的实现。所有在编译时“连接”的都将在运行时调用。
【问题讨论】:
-
可能不可能。在我看来,您基本上想在每个编译单元的基础上更改
notify的行为,而不更改notify。我的理解是,这只能通过运行时机制来完成。我会等着看专家对此有什么看法。 -
请重新表述您的问题,因为很难理解您到底想要什么。 C++ 还没有任何迭代所有定义的符号机制,因此如果你想实现 get-all-defined-update-functions-and-call-them-at-compile-time,那么它不是可能的。您需要创建某种模板列表并手动调用它的成员。
-
如果你专注于你想要完成的事情,而不是专注于你不喜欢的方法,也许你的问题会更容易理解?一个很好的问题/需求陈述,而不是跳入失败的解决方案?
-
感谢您的反馈,我会尽量说清楚。
标签: c++ templates metaprogramming observer-pattern compile-time