使用概念或 SFINAE 检查类是否具有带有 std::array 参数的模板化成员函数 [英] Use concepts or SFINAE to check if class has a templated member function with a std::array parameter

查看:67
本文介绍了使用概念或 SFINAE 检查类是否具有带有 std::array 参数的模板化成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用概念和/或类型特征检测类是否具有带有 std::array 参数的成员函数.

I want to detect, using concepts and/or type traits, if a class has a member function with a std::array parameter.

例如:下面的类将传递这个概念.

For example: Class below would pass the concept.

class OStreamRealizationGood
{
    template<size_t size>
    uint8_t send(std::array<uint8_t, size> array)
};

到目前为止,我使用了一个概念技巧.诀窍是将大小定义为 0.所以我的概念是这样的:

Up until now, I have used a trick for concepts. The trick is defining the size to 0. So my concept looks like this:

template<typename Candidate>
concept OStream = requires(Candidate candidate, std::array<uint8_t, 0> array)
{
    {candidate.send(array)} -> std::same_as<uint8_t>;
};

这个技巧适用于模板化函数,但它并不是我真正需要的.这不是我需要的东西,因为下面的课程也会遵守,但我希望它不会.

That trick works for a templated function, but it isn't really the thing that I need. It isn't the thing that I need because the class below would also comply, but I would like that it doesn't.

class OStreamRealizationBad
{
    uint8_t send(std::array<uint8_t, 0> array)
};

问题

有没有办法写这个来确保 send(array) 是一个模板函数?

我有一个使用 declval(size_t) 的想法,如下图所示,但这不适用于原始类型.

I had an idea of using declval(size_t) as in the picture below, but that doesn't work for primitive types.

template<typename Candidate>
concept OStream = requires(Candidate candidate, std::array<uint8_t, declval(size_t)> array)
{
    {candidate.send(array)} -> std::same_as<uint8_t>;
};

另一个行不通的想法是递归概念:

Another idea that doesn't work was recursing the concepts:

template<typename Candidate, size_t size>
concept HasSendImpl = requires(Candidate candidate, std::array<uint8_t, size> array)
{
    {candidate.send(array)} -> std::same_as<uint8_t>;
};

template<typename Candidate>
concept HasSend = requires(size_t size)
{
        requires HasSendImpl<Candidate, size>;
};

补充问题

另外,我不明白为什么上面的例子不起作用.

Additional question

Additionally, I don't understand why the example above doesn't work.

推荐答案

有没有办法写这个来确保 send(array) 是一个模板函数?

您可以在约束中使用 template 关键字来表示 send 需要是一个模板函数:

You can use the template keyword in the constraint to signify that send needs to be a template function:

template<typename T, std::size_t size>
concept GoodRealization = requires(T t, std::array<uint8_t, size> array) {
    { t.template send<size>(array) } -> std::same_as<uint8_t>;
};

演示.

请注意,这不会拒绝重载发送的带有非模板和模板函数的类型:在重载解析中两者都是可行的候选者,非模板重载可能是最佳候选者(考虑到重载的常规规则)分辨率).

Note that this will not reject a type that overloads send with a non-template and a template function: of both are viable candidates in overload resolution, the non-template overload could be the best candidate (given the regular rules of overload resolution).

这篇关于使用概念或 SFINAE 检查类是否具有带有 std::array 参数的模板化成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆