如何编写C++概念以检查模板参数是否为指定结构体的成员类型
如何编写C++概念以检查模板参数是否为指定结构体的成员类型
嘿,我瞅你这段代码里的IsMessages概念写法有点问题哦——它根本没把模板参数T和Messages的成员类型关联起来!现在不管你传什么类型进去(哪怕是int),这个概念都会返回true,因为它只是在验证Messages结构体里存在A类型,完全没管T到底是什么。
咱们来修正一下,实现真正的检查逻辑:
方案一:直接匹配成员类型(适合成员类型少的情况)
如果Messages里的成员类型不多(比如只有A和B),直接用std::same_as概念来逐个匹配就很清晰:
#include <iostream> #include <concepts> // 记得包含这个头文件才能用标准概念 struct Messages { struct A{}; struct B{}; }; template<typename T> concept IsMessagesMember = std::same_as<T, Messages::A> || std::same_as<T, Messages::B>; template<typename Type> void onMessage(Type&&) { if constexpr (IsMessagesMember<Type>) { std::cout << "Messages msg\n"; } else { std::cout << "Generic msg\n"; } } // 测试一下效果 int main() { Messages::A a; Messages::B b; int num; onMessage(a); // 输出:Messages msg onMessage(b); // 输出:Messages msg onMessage(num); // 输出:Generic msg return 0; }
方案二:用基类统一标记(适合成员类型多的情况)
要是以后Messages会加很多成员类型,一个个写std::same_as太麻烦,咱们可以给所有成员类型加个共同的基类,然后用std::derived_from来检查:
#include <iostream> #include <concepts> struct Messages { // 给所有成员类型一个统一的基类 struct InternalBase {}; struct A : InternalBase {}; struct B : InternalBase {}; struct C : InternalBase {}; // 新增类型直接继承基类就行,不用改概念 }; template<typename T> concept IsMessagesMember = std::derived_from<T, Messages::InternalBase>; template<typename Type> void onMessage(Type&&) { if constexpr (IsMessagesMember<Type>) { std::cout << "Messages msg\n"; } else { std::cout << "Generic msg\n"; } } // 测试新增类型 int main() { Messages::C c; onMessage(c); // 输出:Messages msg return 0; }
这样以后给Messages加新的成员类型,只要让它继承InternalBase,就会自动被概念识别,不用修改概念本身,扩展性更好。
还有些更复杂的黑魔法方式(比如用ADL),但可读性太差,一般没必要用,上面两种方案足够覆盖大部分场景啦。
备注:内容来源于stack exchange,提问作者edwinc
相关产品推荐
相关产品推荐

