【问题标题】:Use concepts or SFINAE to check if class has a templated member function with a std::array parameter使用概念或 SFINAE 检查类是否具有带有 std::array 参数的模板化成员函数
【发布时间】:2021-01-29 15:20:01
【问题描述】:

简介

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

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

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

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

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

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

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

问题

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

我尝试过的事情

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

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

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

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>;
};

补充问题

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

【问题讨论】:

  • 为什么发送函数必须是模板?另外,您为什么要问与标题中的问题不同的问题?最好调整一下题名。
  • 首先我想说明我从事嵌入式开发和动态内存使用的工作。我正在编写一个“接口”OStream,它必须具有 C++ 样式发送和 C 样式发送(即send(uint8_t&amp; array, size_t size))。因此,C++ 风格的函数将是首选,但是当在编译时大小未知时,将调用 C 风格的函数。为了让 C++ 风格的函数在没有动态内存的情况下工作并且足够灵活,它必须被模板化。
  • 是的,我应该重新命名问题,事情是存在类似的问题,但他们并没有解决这个问题。他们执行模板化函数或成员函数,或者在某些情况下两者都执行,但它们不能解决这个问题。编辑:重命名。

标签: c++ arrays metaprogramming typetraits c++-concepts


【解决方案1】:

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

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

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>;
};

DEMO.

请注意,这不会拒绝使用非模板和模板函数重载发送的类型:两者都是重载决议中可行的候选者,非模板重载可能是最佳候选者(鉴于常规的重载规则分辨率)。

【讨论】:

  • 这不是问题的完全解决方案......这更像是针对问题的具体情况的半生不熟的工作。我不相信 C++20 中可用功能的问题有一个通用的解决方案。也许,一旦反射 TS 可用,就可以编写一些验证模板的代码......
  • 由于我也认为不存在通用解决方案,所以我会接受这个。
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
相关资源
最近更新 更多