使用模板化成员函数显式实例化模板类

Posted

技术标签:

【中文标题】使用模板化成员函数显式实例化模板类【英文标题】:Explicit instantiation of template class with templated member functions 【发布时间】:2021-10-21 15:08:49 【问题描述】:

类定义如下:


template <typename T>
class A 
    private:
    T a;

    public:
    A(T& a) : a_(a)  

    template <typename D>
    void Eval(D& arg)
    
        // ...
    
;

template A<int>;

我想显式实例化一个类的实例,并且我希望这个类有一个 Eval 的显式实例化。这里的目的是获取一个避免歧义的成员函数指针:

auto eval_ptr = &A<int>::Eval;

【问题讨论】:

你想在这里避免什么“歧义”? 当我尝试获取指向方法的指针时,会导致错误:“对'Eval'的引用不明确”-错误 【参考方案1】:

歧义与类的模板实例化没有任何关系,它是由Eval 也是模板化函数引起的。

&amp;A&lt;int&gt;::Eval 不指向函数,它指向模板。而且没有像“指向模板的指针”这样的类型。

如果你想要一个指向A&lt;int&gt;::Eval的指针,你还需要指定D

auto eval_ptr = &amp;A&lt;int&gt;::Eval&lt;int&gt;; 例如就可以正常工作。

附录:在语法意义上确实存在指向模板的指针,但没有任何类型可以让对象拥有其中之一。必须立即将它们投射/衰减到特定的过载才能使用,这在这里不起作用,因为您想将其存储在 auto 中。

例如:以下内容很好,因为Eval 显然只有一个“版本”可以表示:

void bar(void (A<int>::*arg)(int&)) 

void foo() 
    bar(&A<int>::Eval);

【讨论】:

【参考方案2】:

非常简单的解决方案是指定两个模板参数:

template <typename T>
class A

private:
    T a;

public:
    A(T &a) : a_(a) 

    template <typename D>
    void Eval(D &arg)
    
        arg+=1;
    
;
int main()

    auto p = &A<int>::Eval<int>;

【讨论】:

以上是关于使用模板化成员函数显式实例化模板类的主要内容,如果未能解决你的问题,请参考以下文章

std::async 与共享指针模板化成员函数

MSVC:显式模板实例化失败,而隐式实例化成功

模板化成员函数不能从同一个类调用非模板化成员函数,C++

模板化类的模板化成员方法可以在类定义之外定义吗

类和对象之模板

为啥未使用的成员模板函数的类模板实例化失败