【问题标题】:How to make a function call via pointer-to-member-function to a templated function?如何通过指向成员函数的指针对模板化函数进行函数调用?
【发布时间】:2021-11-18 10:12:54
【问题描述】:

我尝试编译以下代码。

#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++ 标准中在哪里定义了这种行为?

【问题讨论】:

  • 编译,但行为未定义,因为fun 缺少return
  • 我想不出用这个指针调用函数的语法应该是什么。如果你不知道如何使用指向成员的指针或如何传递模板的参数,阅读一些 C++ 介绍书。
  • 调用成员指针的语法是(o.*f)()。在这种情况下,对象是d,函数指针是func_ptr&lt;T&gt;,对于某些类型T。没有什么特别模棱两可或语言法律问题。
  • 无论你用什么书来学习 C++,当它告诉你如何声明一个指向成员函数的指针,但没有告诉你如何使用它时,这对你造成了伤害。

标签: c++ templates inheritance language-lawyer member-function-pointers


【解决方案1】:

但是,我想不出通过这个指针调用函数的语法应该是什么。它的语法是什么?

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

它是如何解释的? C++ 标准中在哪里定义了这种行为?

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

在你的定义中

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

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

要使用可变模板,必须提供模板参数。 (模板参数推导只能发生在函数模板和类模板中。)所以func_ptr&lt;int&gt;int (*)() 类型的表达式。然后结合语法(obj.*mem)(args) for 调用指向成员函数的指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-30
    • 2023-03-28
    • 2010-09-13
    • 1970-01-01
    • 2011-12-09
    • 2015-05-06
    • 1970-01-01
    • 2012-12-16
    相关资源
    最近更新 更多