当可以从参数推导出类型时,简化对类模板静态方法的调用

问题描述 投票:0回答: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;
};

int main()
{
    A<int> a( 5 );

    std::cout << A<int>::IsValid( a ) << "\n";   // <---
    return 0;
}

我发现第18行(标有

<---
)写起来很麻烦。 我想知道为什么我不能将我的方法称为
A::IsValid( a )
,因为类型
T
可以很容易地从输入
a
中推导出来?有什么方法可以以不同的方式编写它,以便这成为可能吗?

我发现的最接近的SO问题是:在不指定实例化的情况下调用类模板的静态方法的方法?,但这个问题本质上是不同的,因为它没有参数来推断类型。

c++ templates
1个回答
0
投票

不,这是不可能的。

首先考虑只有 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);
 }

或者使其成为非静态成员函数。

© www.soinside.com 2019 - 2024. All rights reserved.