如何编写判断方法不存在的C++ Concept?解决模板特化歧义
解决C++ Concept歧义:区分仅含单个方法与含两个方法的类
你的问题根源在于HasOne概念没有排除同时拥有Two()方法的类——所有满足HasTwo的类自然也满足HasOne,导致模板特化时出现歧义,编译器不知道该选哪一个版本的Do。
要解决这个问题,只需要修改HasOne概念,让它不仅要求类存在One()方法,还要求不存在Two()方法。在C++20的Concept中,可以通过!requires语法来否定一个约束条件:
template<typename T> concept HasOne = requires { T::One(); } && !requires { T::Two(); };
这样一来,WithTwo类因为拥有Two()方法,就不再满足HasOne概念,模板特化的歧义就消除了。
以下是修改后的完整可运行代码:
#include <iostream> template<typename T> struct Do {}; // 同时拥有One()和Two()方法 template<typename T> concept HasTwo = requires { T::One(); T::Two(); }; // 仅拥有One()方法,且没有Two()方法 template<typename T> concept HasOne = requires { T::One(); } && !requires { T::Two(); }; // 针对拥有两个方法的类的特化 template<HasTwo T> struct Do<T> { static void Something() { T::One(); T::Two(); }}; // 针对仅拥有一个方法的类的特化 template<HasOne T> struct Do<T> { static void Something() { T::One(); }}; // 示例类 struct WithOne { static void One() { std::cout << "1"; } }; struct WithTwo { static void One() { std::cout << "1"; } static void Two() { std::cout << "2"; } }; int main() { Do<WithOne>::Something(); // 输出:1 std::cout << std::endl; Do<WithTwo>::Something(); // 输出:12 return 0; }
运行这段代码后,WithOne会调用仅输出"1"的版本,WithTwo会调用输出"12"的版本,完全符合预期,不会再出现歧义错误。
内容的提问来源于stack exchange,提问作者c z
相关产品推荐
相关产品推荐

