I tried to compile the following code.
#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?
}
To my surprise, this compiled in both clang and gcc. This gives me the idea that somehow we should be able to call fun
by func_ptr
. However, I cannot think of what the syntax should be to call the function by this pointer. What is the syntax for it and how is it explained?
Also another thing is, I cannot think of a reason for this to compile. Where is this behavior defined in C standard?
CodePudding user response:
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
is a variable template. There are very few rules in the Standard specifically about variable templates, but they are allowed in C 17 and later by [temp.pre] paragraphs 1 and 2.
In your definition
template<class T>
T (Derived::*func_ptr)() = &Base::fun;
the expression &Base::fun
is a pointer to overloaded function, as described in [over.over]. When each specialization of the func_ptr
template is instantiated, it has a specific pointer-to-function type T (*)()
as the target, and the correct template argument for Base::fun<T>
can be deduced from that.
To use a variable template, template arguments must be provided. (Template argument deduction can only happen for function templates and class templates.) So func_ptr<int>
is an expression of type int (*)()
. Then that's combined with the syntax (obj.*mem)(args)
for
calling a pointer to member function.