能否检测类是否存在符合指定签名、支持任意类型参数的模板成员方法?
C++检测模板成员方法的解决方案
核心说明
不存在能验证「模板成员方法对任意类型T都可实例化」的绝对检测方案:C++模板支持显式特化、SFINAE约束,理论上无法穷举所有可能的T来验证实例化合法性。但针对你提到的两类实际场景(接收std::vector<T>的模板方法、接收Eigen派生类的模板方法),可以通过「构造符合参数约束的标准测试类型」来完成检测,完全覆盖工程使用需求。
场景1:检测接收std::vector的模板method
你只需要用任意普通类型(比如int)构造vector作为测试入参即可,只要测试通过,就说明该模板方法符合template<typename T> int method(std::vector<T>)的签名要求:
C++20 Concept 实现
#include <type_traits> #include <vector> template<typename T> concept HasVectorMethod = requires(T obj, std::vector<int> test_vec) { { obj.method(test_vec) } -> std::same_as<int>; }; // 验证示例 static_assert(HasVectorMethod<Foo>); // 你的Foo类可通过检测
C++11/14 SFINAE 实现
#include <type_traits> #include <vector> template<typename T, typename = void> struct has_vector_method : std::false_type {}; template<typename T> struct has_vector_method<T, typename std::enable_if< std::is_same< decltype(std::declval<T>().method(std::declval<std::vector<int>>())), int >::value >::type > : std::true_type {}; // 辅助变量 template<typename T> constexpr bool has_vector_method_v = has_vector_method<T>::value; // 验证示例 static_assert(has_vector_method_v<Foo>, "Foo does not have required method");
场景2:检测接收Eigen::ArrayBase派生类的模板func
和上面的逻辑一致,构造一个最简单的Eigen数组类型作为测试入参即可,只要测试通过,所有Eigen::ArrayBase的派生类(包括row、col、segment返回的块类型)都可以正常调用该方法:
C++20 Concept 实现
#include <type_traits> #include <Eigen/Core> // 构造最小测试用Eigen数组类型 using TestEigenArr = Eigen::Array<double, 1, 1>; template<typename T> concept HasEigenFunc = requires(T obj, TestEigenArr test_arr) { { obj.func(std::move(test_arr)) } -> std::same_as<void>; }; // 验证示例 static_assert(HasEigenFunc<Foo>); // 你的Foo类可通过检测
C++11/14 SFINAE 实现
#include <type_traits> #include <Eigen/Core> using TestEigenArr = Eigen::Array<double, 1, 1>; template<typename T, typename = void> struct has_eigen_func : std::false_type {}; template<typename T> struct has_eigen_func<T, typename std::enable_if< std::is_same< decltype(std::declval<T>().func(std::move(std::declval<TestEigenArr>()))), void >::value >::type > : std::true_type {}; // 辅助变量 template<typename T> constexpr bool has_eigen_func_v = has_eigen_func<T>::value; // 验证示例 static_assert(has_eigen_func_v<Foo>, "Foo does not have required func");
边界说明
如果有人故意编写只对极少数特殊T生效的模板成员,上述检测会存在漏判,但这类写法在实际工程中没有任何实用价值,不需要额外考虑。
内容的提问来源于stack exchange,提问作者Aisec Nory
相关产品推荐
相关产品推荐

