如何通过指向成员函数的指针对模板函数进行函数调用?

How to make a function call via pointer-to-member-function to a templated function?

我尝试编译了以下代码。

#include <iostream>

class Base
{
public:
    template <typename T>
    T fun()
    {
        std::cout<<"CALLED!"<<std::endl;
        return T();
    }
};

class Derived : public Base 
{ 

};

template<class T>
T (Derived::*func_ptr)() = &Base::fun;

int main()
{
    Derived d;
    ///how to call?
}

令我惊讶的是,它是用 clang 和 gcc 编译的。这让我想到我们应该能够通过 func_ptr 调用 fun。但是,我想不出用这个指针调用函数的语法应该是什么。它的语法是什么,如何解释?

还有一件事,我想不出编译的理由。 C++ 标准中在哪里定义了这种行为?

However, I cannot think of what the syntax should be to call the function by this pointer. What is the syntax for it?

(d.*func_ptr<int>)();  // or other template argument

How is it explained? Where is this behavior defined in C++ standard?

func_ptr是变量模板。标准中很少有专门关于变量模板的规则,但在 C++17 及更高版本中 [temp.pre] 第 1 段和第 2 段允许使用它们。

在你的定义中

template<class T>
T (Derived::*func_ptr)() = &Base::fun;

表达式 &Base::fun 是指向重载函数的指针,如 [over.over] 中所述。当实例化 func_ptr 模板的每个特化时,它都有一个特定的指向函数类型 T (*)() 作为目标,并且可以从中推导出 Base::fun<T> 的正确模板参数。

要使用变量模板,必须提供模板参数。 (模板参数推导只能发生在函数模板和 class 模板上。)因此 func_ptr<int> 是类型 int (*)() 的表达式。然后结合语法 (obj.*mem)(args) for 调用指向成员函数的指针。