如何在C++ requires表达式中实现成员函数存在性的逻辑或判断
修复C++泛型函数的requires约束逻辑或问题
错误原因
你原来的requires表达式写法存在逻辑误区:{ t.has_foo() || t.has_bar(); }这种写法要求整个表达式完全合法,也就是T类型必须同时拥有has_foo()和has_bar()两个成员函数——C++的requires表达式不会对逻辑运算符做短路求值,它会检查表达式里所有子项的有效性,所以Foo没有has_bar()、Bar没有has_foo()时,整个约束都会失败。
正确的逻辑或约束写法
要实现“满足任一成员函数存在即可”的约束,需要把两个条件拆成独立的requires检查,再用||连接,写法如下:
template<typename T> bool check(const T& t) // 两个独立的requires约束,只要其中一个成立就满足条件 requires (requires (T t) { t.has_foo(); }) || (requires (T t) { t.has_bar(); }) { if constexpr (requires { t.has_foo(); }) { if (t.has_foo()) std::cout << "has foo\n"; else std::cout << "no foo\n"; } if constexpr (requires { t.has_bar(); }) { if (t.has_bar()) std::cout << "has bar\n"; else std::cout << "no bar\n"; } return true; }
也可以简化为更紧凑的写法:
template<typename T> bool check(const T& t) requires requires(T t) { t.has_foo(); } || requires(T t) { t.has_bar(); } { // 函数体不变 }
修复后的完整代码
#include <iostream> struct Foo { bool has_foo() const { return true; } }; struct Bar { bool has_bar() const { return true; } }; template<typename T> bool check(const T& t) requires (requires (T t) { t.has_foo(); }) || (requires (T t) { t.has_bar(); }) { if constexpr (requires { t.has_foo(); }) { if (t.has_foo()) std::cout << "has foo\n"; else std::cout << "no foo\n"; } if constexpr (requires { t.has_bar(); }) { if (t.has_bar()) std::cout << "has bar\n"; else std::cout << "no bar\n"; } return true; } int main() { check(Foo()); check(Bar()); return 0; }
编译运行后会输出:
has foo has bar
内容的提问来源于stack exchange,提问作者Steve Lorimer
相关产品推荐
相关产品推荐

