I have a class template, and inside it a static method whose input argument is the class itself. For example:
#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;
}
I find line 18 (marked with <---
) very cumbersome to write over and over.
I wonder why I cannot call my method as A::IsValid( a )
, given that the type T
can be easily deduced from the input a
? Is there any way to write it differently so that this is possible?
The closest SO question I found was: Way to call a static method of a class template without specifying an instantiation?, but that question is inherently different since it has no arguments to deduce the type from.
No, it is not possible.
First consider that only CTAD (Class template argument deduction) deduces template arguments for class templates that are about to be constructed based on types of passed function arguments. Though, when you call the static method, no object is constrcuted.
Next consider that A<U>
can be specialized to have a IsValid(const A<V>&)
member. In other words, there is no 1 to 1 relation between the T
on the type of the argument to IsValid(const A<T>&)
and the T
in A<T>::IsValid
. For example:
template <> class A<double> {
static bool IsValid(const A<int>& a) { return true; }
};
Now there would be no way to tell which instantitation of A
is wanted when you call A::IsValid( A<int>{} )
. Is this calling a method of A<int>
or of A<double>
? Does it actually matter that this method is member of a class? Which brings me to..
You can write a free function:
auto IsValid(const auto& a) {
return decltype(a)::IsValid(a);
}
Or make it a non-static member function.