简体   繁体   English

如何使用 static_assert 来检查函数签名是否正确

[英]How to static_assert to check function signature is correct

The Code编码

I have a templated type that follows the Observer Pattern .我有一个遵循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;
};

The above works great but only so long as the Observer is a templated type.以上工作很好,但ObserverObserver是模板类型。 So I can modify the template signature and accept any type, regardless of whether they are templated.所以我可以修改模板签名并接受任何类型,无论它们是否被模板化。

    template <typename Observer>
    void AddObserver(Observer& observer)
    {
        observers.push_back([&](const T& value) { observer.OnEvent(value); });
    }

The Issue问题

But now there aren't any compile time checks on type matching between the Subject and the Observer.但是现在没有对 Subject 和 Observer 之间的类型匹配进行任何编译时检查。 ( EDIT it has been pointed out that there is no guarantee that Observer<T> actually uses T in its OnEvent function signature) 编辑已经指出不能保证Observer<T>在其OnEvent函数签名中实际使用T

I'd like to add a static cast to the function that checks that the two types Subject<**T**> and the Observer::OnEvent(const **T**&) are the same, to prevent automagic type conversions.我想向函数添加一个静态转换,以检查两种类型Subject<**T**>Observer::OnEvent(const **T**&)是否相同,以防止自动类型转换. Something like the below.像下面这样的东西。

static_cast(std::is_same<T, **type_of_first_param**(Observer::OnEvent)>::value, "Subject/Observer type mistatch.");

Possible approach that I need help with我需要帮助的可能方法

If I cannot extract the type from the function signature, perhaps I can construct a function signature to which I can compare it?如果我无法从函数签名中提取类型,也许我可以构建一个可以与之比较的函数签名?

static_cast(std::is_same<**Observer::MadeUpFunc(const T&)**, Observer::OnEvent>::value, "Subject/Observer type mistatch.");

I'm investigating this QA , and I'm pretty sure it holds the answer I need, just need some time and perhaps guidance to figure it out.我正在调查这个 QA ,我很确定它包含我需要的答案,只需要一些时间和指导来解决它。

I have tried the following, but get the compile time error我尝试了以下操作,但出现编译时错误

typename specifier refers to non-type member 'OnEvent' in 'Observer' typename 说明符指的是“Observer”中的非类型成员“OnEvent”

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

What I have tried我试过的


It's not clear to me what restrictions you want here.我不清楚你在这里想要什么限制。 The most restrictive would be to enforce something like:最严格的是强制执行以下操作:

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

where the OnEvent function couldn't be a template , it couldn't return anything aside from void , it would be required to be marked const , and it would have to take const T& , even if T is int . OnEvent函数不能是template ,它不能返回除void之外的任何内容,它需要被标记为const ,并且它必须采用const T& ,即使Tint

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM