我有以下案例
template<typename Class>
concept has_member = requires (Class t)
{
// How can I write only if either of the following conditions is satisfied?
{t.isInterface() }->std::same_as<bool>;
// or
{t.canInterface() }->std::same_as<bool>;
// or
// ... more conditions!
};
struct A {
bool isInterface() const { return true; }
};
struct B {
bool canInterface() const { return true; }
};
void foo(const has_member auto& A_or_B)
{
// do something
}
int main()
{
foo(A{}); // should work
foo(B{}); // should work
}
正如我在代码注释中提到的,我想从逻辑上或要求(在单个
concepts
中),以便类A
和B
可以传递给doSomething()
。
据我所知,目前的概念是检查所有需求,这意味着逻辑与。 如果我把它拆成不同的概念,一切都会起作用,但我需要编写更多的概念来满足意图。
可以合二为一吗?类似伪代码的东西
template<typename Class>
concept has_member = requires (Class t)
{
{t.isInterface() }->std::same_as<bool> || {t.canInterface() }->std::same_as<bool>;
// ...
};
可以合二为一吗?
是的,这是可能的。您可以将两个
requires
的合取写成如下:
template<typename Class>
concept has_member =
requires (Class t) { {t.isInterface() }->std::same_as<bool>; }
|| //---> like this
requires (Class t) { {t.canInterface() }->std::same_as<bool>;};
// ... more conditions!
任何时候你想开始构建概念,你都应该从使用点开始。也就是说,您将出于某种目的使用一些模板参数的地方。
这意味着,您从foo
开始。
foo
如何使用此界面“做某事”?它不可能这么简单:
void foo(const has_member auto& A_or_B)
{
A_or_B.isInterface();
}
对于某些 has_member
对象来说,这将是一个编译错误。所以你需要这样做:
void foo(const has_member auto& A_or_B)
{
if constexpr(<stuff>)
A_or_B.isInterface();
else
A_or_B.hasInterface();
}
其中 <stuff>
是一些编译时条件检查,以查看对象具有哪个实际接口。您可以拼出
requires
子句,但这会不必要地冗长。所以只需将它们固定在一个概念中即可:
template<typename T>
concept has_is_interface = requires (Class t)
{
{t.isInterface() }->std::same_as<bool>;
};
template<typename T>
concept has_can_interface = requires (Class t)
{
{t.canInterface() }->std::same_as<bool>;
};
现在,你的问题已经有了答案:
template<typename Class>
concept has_member =
(has_is_interface || has_can_interface) &&
requires (Class t)
{
// ... more conditions!
};
您
可能想要的是一些可以调用适当的成员接口的免费函数:
bool do_is_interface(has_is_interface auto const& is_if)
{
return is_if.is_interface();
}
bool do_is_interface(has_can_interface auto const& is_if)
{
return is_if.can_interface();
}
然后你的概念看起来像:
template<typename Class>
concept has_member =
requires (Class t)
{
{ do_is_interface(t) } -> std::same_as<bool>
// ... more conditions!
};