我有一个类模板,其中有一个静态方法,其输入参数是类本身。 例如:
#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;
}
我发现第18行(标有
<---
)写起来很麻烦。
我想知道为什么我不能将我的方法称为 A::IsValid( a )
,因为类型 T
可以很容易地从输入 a
中推导出来?有什么方法可以以不同的方式编写它,以便这成为可能吗?
我发现的最接近的SO问题是:在不指定实例化的情况下调用类模板的静态方法的方法?,但这个问题本质上是不同的,因为它没有参数来推断类型。
不,这是不可能的。
首先考虑只有 CTAD(类模板参数推导)会根据传递的函数参数的类型来推导即将构造的类模板的模板参数。但是,当您调用静态方法时,不会构造任何对象。
接下来考虑
A<U>
可以专门化为 IsValid(const A<V>&)
成员。换句话说,T
的参数类型上的IsValid(const A<T>&)
和T
中的A<T>::IsValid
之间不存在1对1的关系。例如:
template <> class A<double> {
static bool IsValid(const A<int>& a) { return true; }
};
现在,当您调用
T
时,将无法判断需要哪个 A::IsValid( A<int>{} )
实例化。这是调用 A<int>
还是 A<double>
的方法吗?该方法是类的成员真的很重要吗?这让我想到..
您可以编写一个免费函数:
auto IsValid(const auto& a) {
return decltype(a)::IsValid(a);
}
或者使其成为非静态成员函数。