具有 C++20 概念的干净静态接口



我试图使用 C++20 概念创建一个静态接口,以下代码似乎可以完成这项工作:

template <class FOO>
concept FooConcept = requires {
static_cast<void (FOO::*)(int)>(&FOO::operator());
static_cast<void (FOO::*)(char)>(&FOO::operator());
};

特别是,如果类重载两次operator(),则类FOO满足FooConcept:分别使用int参数和char参数。

这个解决方案似乎工作正常,但看起来并不漂亮。事实上,我更喜欢以下形式:

template <class FOO>
concept FooConcept = requires (FOO foo, int i, char c) {
{ foo(i) } -> std::same_as<void>;
{ foo(c) } -> std::same_as<void>;
};

template <class FOO>
concept FooConcept = std::invocable<FOO, int> && std::invocable<FOO, char>;

但是,由于隐式转换,这些方法不起作用(请参阅这篇文章)。有没有更好、更"语义"的方式来表达这种约束?

使用一些帮助程序和非final类,您可以执行以下操作:

template <typename T>
struct DeletedOperator : T
{
using T::operator ();
template <typename ... Ts>
void operator()(Ts&&...) = delete;
template <typename ... Ts>
void operator()(Ts&&...) const = delete;
};
template <class FOO>
concept FooConcept = requires (DeletedOperator<FOO> foo, int i, char c) {
{ foo(i) } -> std::same_as<void>;
{ foo(c) } -> std::same_as<void>;
};

演示

我认为我们可以通过调整助手来摆脱非final约束。

最新更新