如何将非静态成员函数作为模板参数传递给另一个成员函数?
How to pass non-static member function as template argument to another member function?
我想做这样的事情:
struct S
{
void mf() {};
template <auto f>
void func()
{
f();
}
};
int main()
{
S x;
x.func<x.mf>();
}
然而,这些是错误:
error: no matching function for call to 'S::func<x.S::mf>()'`
note: candidate: 'template<auto f> void S::func()'
note: template argument deduction/substitution failed:
error: could not convert 'x.S::mf' from '<unresolved overloaded function type>' to 'void (S::*)()'
我不确定我是否理解我做错了什么。
为什么 x.mf
没有解决,因为我已经实例化了 x
?我该怎么做?
通过指针调用成员函数可能非常棘手。
您想将成员函数指针传递给 S::mf
like so:
struct S
{
void mf () {std::cout << "called mf\n";};
template <auto f>
void func ()
{
(this->*f)();
}
};
int main()
{
S x;
x.func<&S::mf>();
}
x.mf
不是类型而是 member-function 指针。
我们必须将它作为参数传递。
这是您修改后的示例(不确定您要做什么)。
#include <iostream>
struct S
{
int i=123;
void mf () { std::cout << "i=" << i << '\n'; };
template <typename f>
void func (f fnct)
{
(this->*fnct)();
}
};
int main()
{
S x{456};
x.func(&S::mf);
}
Why is x.mf
not resolved since I already instantiated x
?
因为它不是一个有效的语法。在那里你需要通过运算符 &
提及成员函数,这意味着你应该有
x.func<&S::mf>();
// ^^^^^^^^
这样模板参数就会被推导出一个对应的成员函数指针。即void(S::*)()
.
How do I make this work?
第二个问题是,函数调用 f()
应该是 call through a member function pointer。这与正常的函数调用不同。
用实例调用成员函数指针的传统方式是
(this->*f)();
然而,由于 c++17 this is more convenient way using more generic liberary function, so calledstd::invoke
from <functional>
header.
这意味着您可以通过成员函数指针进行更具可读性的调用。
#include <functional> // std::invoke
template <auto f>
void func()
{
std::invoke(f, this);
}
我想做这样的事情:
struct S
{
void mf() {};
template <auto f>
void func()
{
f();
}
};
int main()
{
S x;
x.func<x.mf>();
}
然而,这些是错误:
error: no matching function for call to 'S::func<x.S::mf>()'`
note: candidate: 'template<auto f> void S::func()'
note: template argument deduction/substitution failed:
error: could not convert 'x.S::mf' from '<unresolved overloaded function type>' to 'void (S::*)()'
我不确定我是否理解我做错了什么。
为什么 x.mf
没有解决,因为我已经实例化了 x
?我该怎么做?
通过指针调用成员函数可能非常棘手。
您想将成员函数指针传递给 S::mf
like so:
struct S
{
void mf () {std::cout << "called mf\n";};
template <auto f>
void func ()
{
(this->*f)();
}
};
int main()
{
S x;
x.func<&S::mf>();
}
x.mf
不是类型而是 member-function 指针。
我们必须将它作为参数传递。
这是您修改后的示例(不确定您要做什么)。
#include <iostream>
struct S
{
int i=123;
void mf () { std::cout << "i=" << i << '\n'; };
template <typename f>
void func (f fnct)
{
(this->*fnct)();
}
};
int main()
{
S x{456};
x.func(&S::mf);
}
Why is
x.mf
not resolved since I already instantiatedx
?
因为它不是一个有效的语法。在那里你需要通过运算符 &
提及成员函数,这意味着你应该有
x.func<&S::mf>();
// ^^^^^^^^
这样模板参数就会被推导出一个对应的成员函数指针。即void(S::*)()
.
How do I make this work?
第二个问题是,函数调用 f()
应该是 call through a member function pointer。这与正常的函数调用不同。
用实例调用成员函数指针的传统方式是
(this->*f)();
然而,由于 c++17 this is more convenient way using more generic liberary function, so calledstd::invoke
from <functional>
header.
这意味着您可以通过成员函数指针进行更具可读性的调用。
#include <functional> // std::invoke
template <auto f>
void func()
{
std::invoke(f, this);
}