代码
我有一个遵循 Observer Pattern 的模板类型.
template <typename T>
class Subject {
public:
template <template<typename> typename Observer>
void AddObserver(Observer<T>& observer)
{
observers.push_back([&](const T& value) { observer.OnEvent(value); });
}
void Event(const T& value) const
{
for (auto& o : observers) {
o.OnEvent(value)
}
}
private:
std::vector<std::function<void(const T&)>> observers;
};
上面的方法很好用,但前提是 Observer
是一个模板类型。因此我可以修改模板签名并接受任何类型,无论它们是否是模板化的。
template <typename Observer>
void AddObserver(Observer& observer)
{
observers.push_back([&](const T& value) { observer.OnEvent(value); });
}
问题
但是现在没有对主题和观察者之间的类型匹配进行任何编译时检查。 (编辑有人指出,不能保证 Observer<T>
实际上在其 T
函数签名中使用 OnEvent
)
我想向函数添加静态强制转换,以检查两种类型 Subject<**T**>
和 Observer::OnEvent(const **T**&)
是相同的,以防止自动类型转换。类似于下面的内容。
static_cast(std::is_same<T, **type_of_first_param**(Observer::OnEvent)>::value, "Subject/Observer type mistatch.");
我需要帮助的可能方法
如果我无法从函数签名中提取类型,也许我可以构造一个可以与之比较的函数签名?
static_cast(std::is_same<**Observer::MadeUpFunc(const T&)**, Observer::OnEvent>::value, "Subject/Observer type mistatch.");
我正在调查this QA ,而且我很确定它包含我需要的答案,只是需要一些时间,也许还需要指导来找出答案。
我尝试了以下方法,但出现编译时错误
typename specifier refers to non-type member 'OnEvent' in 'Observer'
static_assert(std::is_same<typename Observer::OnEvent, void (Observer::*)(const T&...)>::value, "");
我尝试过的
- 我已阅读此处的文档 cppreference.com/w/cpp/types
- 我已阅读此处的一些文档 cppreference.com/w/cpp/language ,即函数和模板下的部分
- 我已读过此文 drdobbs.com/cpp/extracting-function-parameter-and-return
- 我看过这些类似 QA Extracting function argument types as a parameter pack , “unpacking” a tuple to call a matching function pointer
最佳答案
我不清楚你想要什么限制。 最严格的限制是强制执行以下内容:
static_assert(std::is_same_v<decltype(&Observer::OnEvent),
void (Observer::*)(const T&) const>);
其中 OnEvent
函数不能是 模板
,它无法返回除 void
之外的任何内容,因此需要被标记为 const
,并且它必须采用 const T&
,即使 T
是 int
。
关于c++ - 如何使用 static_assert 检查函数签名是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63612944/