使用概念或 SFINAE 检查 class 是否具有带有 std::array 参数的模板化成员函数
Use concepts or SFINAE to check if class has a templated member function with a std::array parameter
简介
我想使用概念 and/or 类型特征来检测 class 是否具有带 std::array 参数的成员函数。
例如:
Class 下面会传递这个概念。
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 也符合要求,但我希望它不需要。
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>;
};
附加问题
此外,我不明白为什么上面的例子不起作用。
Is there a way to write this to ensure that send(array)
is a templated function?
您可以在约束中使用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.
请注意,这不会拒绝使用非模板和模板函数重载 send 的类型:两者都是重载决议的可行候选者,非模板重载可能是最佳候选者(给定常规规则重载分辨率)。
简介
我想使用概念 and/or 类型特征来检测 class 是否具有带 std::array 参数的成员函数。
例如: Class 下面会传递这个概念。
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 也符合要求,但我希望它不需要。
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>;
};
附加问题
此外,我不明白为什么上面的例子不起作用。
Is there a way to write this to ensure that
send(array)
is a templated function?
您可以在约束中使用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.
请注意,这不会拒绝使用非模板和模板函数重载 send 的类型:两者都是重载决议的可行候选者,非模板重载可能是最佳候选者(给定常规规则重载分辨率)。