如何static_assert检查功能签名是否正确

问题描述

代码

我有一个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,并且我很确定它可以满足我的需要,只需要一些时间,也许还需要一些指导才能弄清楚。

我尝试了以下操作,但出现了编译时错误

类型名称说明符指的是“观察者”中的非类型成员“事件”。

static_assert(std::is_same<typename Observer::OnEvent,void (Observer::*)(const T&...)>::value,"");

我尝试过的


解决方法

我不清楚您要在此设置哪些限制。 限制性最强的是强制执行以下操作:

static_assert(std::is_same_v<decltype(&Observer::OnEvent),void (Observer::*)(const T&) const>);

其中OnEvent函数不能是template,它不能返回void之外的任何东西,它需要标记为const,并且即使const T&T,也要花费int

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...