如何简化可从参数推导类型的类模板静态方法调用?
问题:简化类模板静态方法的调用方式
用户提供的示例代码:
#include <iostream> template <typename T> class A { public: A( const T& t ) : val(t) {} static bool IsValid( const A<T>& a ) { return (bool)a.val; } private: T val; }; int main() { A<int> a( 5 ); std::cout << A<int>::IsValid( a ) << "\n"; // <--- 希望简化此处调用 return 0; }
用户的疑问:
反复编写A<int>::IsValid(a)十分繁琐,既然类型T可从输入参数a轻松推导,为何不能直接以A::IsValid(a)的形式调用该方法?有没有办法实现这种简化?
可行的简化方案
方案1:封装非成员模板函数(最实用,兼容性好)
写一个顶层的模板辅助函数,让编译器自动推导参数的模板类型,调用时直接写函数名即可:
#include <iostream> template <typename T> class A { public: A( const T& t ) : val(t) {} static bool IsValid( const A<T>& a ) { return (bool)a.val; } private: T val; }; // 新增非成员辅助函数,自动推导T template <typename T> bool IsValid(const A<T>& a) { return A<T>::IsValid(a); } int main() { A<int> a( 5 ); std::cout << IsValid(a) << "\n"; // 简化后的调用 return 0; }
这种方式兼容C++98及以上所有标准,调用起来最简洁,完全不用手动指定模板参数。
方案2:用decltype推导类型
如果不想新增辅助函数,可以利用decltype获取变量的类型,替代手动写A<int>:
std::cout << decltype(a)::IsValid(a) << "\n";
这个写法比原代码简洁,尤其是当模板参数类型名很长的时候,但还是不如方案1的调用方式直观。
方案3:C++20及以上的进阶写法(不推荐,冗余)
可以把静态方法改成模板方法,让它接受任意A<U>类型的参数,但本质上还是需要借助类模板实例来调用,实际意义不大:
template <typename T> class A { public: A( const T& t ) : val(t) {} // 改为模板静态方法,推导参数的模板类型U template <typename U> static bool IsValid( const A<U>& a ) { return (bool)a.val; } private: T val; }; // 调用时可以写: std::cout << A<int>::IsValid(a) << "\n"; // 或者借助CTAD,但还是要写一次类型: std::cout << A{0}::IsValid(a) << "\n";
这种写法并没有比原代码更简洁,不推荐使用。
内容的提问来源于stack exchange,提问作者Blabba
相关产品推荐
相关产品推荐

