【发布时间】: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& array, size_t size))。因此,C++ 风格的函数将是首选,但是当在编译时大小未知时,将调用 C 风格的函数。为了让 C++ 风格的函数在没有动态内存的情况下工作并且足够灵活,它必须被模板化。 -
是的,我应该重新命名问题,事情是存在类似的问题,但他们并没有解决这个问题。他们执行模板化函数或成员函数,或者在某些情况下两者都执行,但它们不能解决这个问题。编辑:重命名。
标签: c++ arrays metaprogramming typetraits c++-concepts