推导成员函数的参数列表
Deducing parameter list of a member function
我们希望能够推断出模板中成员函数调用的参数列表。这是一个更大项目的一部分,该项目最终执行允许调用目标函数的类型转换。
我们的研究得出了 ,这对我们帮助很大。
我们现在一直在为成员函数寻找类似的概念。关键元素在以下 Source 1 代码示例中:
- In main, comment
// Free funct.
: 这演示了自由函数的成功案例,并为自由函数展示了我们想为成员函数实现的目标。
- 在主要部分,评论
Extrinsic call to member function.
和 Problem 1
。这起草了我们尝试支持对成员函数的外部调用的目标语法。
- In
object::exec(...)
: 这起草了对象内部调用的目标语法。
查看演示我们当前研究的第二个代码块:我们知道函数和成员指针之间的区别,并且调用成员需要对象标识。但是我们无法用代码表达我们的知识。第二个代码块没有编译。
获得所示符号的正确符号和模板推导结构是什么?
来源 1
#include <iostream>
void free_funct(int p1, double p2) {
std::cout << "p1=" << p1 << " p2=" << p2 << endl;
}
struct object {
void object_funct(double p1, int p2) const {
std::cout << "p1=" << p1 << " p2=" << p2 << endl;
}
int exec(double p1, int p2) {
// Ultimate goal:
// Wrapper<(???::object_funct> functor3;
// functor_3(p1, p2;)
}
};
template <auto F>
class Wrapper {};
template <typename R, typename... Args, auto (F)(Args...)->R>
struct Wrapper<F>
{
auto operator()(Args... args) const -> R {
return F(args...);
}
};
int main() {
// Free funct.
Wrapper<free_funct> functor1{};
functor1(313, 3.141592);
object object;
// Extrinsic call to member function.
object.object_funct(3.1415926, 313);
// Problem 1:
Wrapper<&object::object_funct> functor2;
// How to express this below
// functor2(3, 1415926, 313);
object.exec(2.718281, 121);
return 0;
}
源代码 2(不编译)
template <auto F>
struct Wrap;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrap<F> {
auto operator()(Args... args) {
return F(args...);
}
};
struct foo {
int bar(float) {
return 1; };
};
int main() {
foo x;
Wrap<&x::bar> f;
f(3.14159265);
return 0;
}
既然您希望Wrapper
通过模板参数包装成员函数指针,您必须知道如何调用成员函数指针。通常我们使用(obj.*mfptr)(args...)
或(optr->*mfptr)(args...)
调用成员函数指针,显然对象本身也是调用操作所必需的。所以在 Wrapper::operator()
中,我们不仅需要每个参数,还需要对象。
template <auto F>
struct Wrapper;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrapper<F> {
// it seems you don't take care of the cvref qualifiers, so I won't write all the overloads.
auto operator()(T obj, Args... args) {
return (obj.*F)(args...);
}
auto operator()(T* obj, Args... args) {
return (obj->*F)(args...);
}
};
实际上,成员函数调用与将对象作为第一个参数的函数调用相似(而不是等于)。所以你必须这样称呼它:
Wrapper<&foo::bar> f;
f(foo{}, 3.14);
编辑:
现在您还希望包装实例,Wrapper
必须使用实例构造:
template <auto F>
struct Wrapper;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrapper<F> {
// I also omit the overloads of pass by reference semantics.
Wrapper(T obj) :instance(std::move(obj)){}
auto operator()(Args... args) {
return (instance.*F)(args...);
}
private:
T instance;
};
int main(){
foo x;
Wrapper<&foo::bar> f{x};
f(3.14);
}
我们希望能够推断出模板中成员函数调用的参数列表。这是一个更大项目的一部分,该项目最终执行允许调用目标函数的类型转换。
我们的研究得出了
我们现在一直在为成员函数寻找类似的概念。关键元素在以下 Source 1 代码示例中:
- In main, comment
// Free funct.
: 这演示了自由函数的成功案例,并为自由函数展示了我们想为成员函数实现的目标。 - 在主要部分,评论
Extrinsic call to member function.
和Problem 1
。这起草了我们尝试支持对成员函数的外部调用的目标语法。 - In
object::exec(...)
: 这起草了对象内部调用的目标语法。
查看演示我们当前研究的第二个代码块:我们知道函数和成员指针之间的区别,并且调用成员需要对象标识。但是我们无法用代码表达我们的知识。第二个代码块没有编译。
获得所示符号的正确符号和模板推导结构是什么?
来源 1
#include <iostream>
void free_funct(int p1, double p2) {
std::cout << "p1=" << p1 << " p2=" << p2 << endl;
}
struct object {
void object_funct(double p1, int p2) const {
std::cout << "p1=" << p1 << " p2=" << p2 << endl;
}
int exec(double p1, int p2) {
// Ultimate goal:
// Wrapper<(???::object_funct> functor3;
// functor_3(p1, p2;)
}
};
template <auto F>
class Wrapper {};
template <typename R, typename... Args, auto (F)(Args...)->R>
struct Wrapper<F>
{
auto operator()(Args... args) const -> R {
return F(args...);
}
};
int main() {
// Free funct.
Wrapper<free_funct> functor1{};
functor1(313, 3.141592);
object object;
// Extrinsic call to member function.
object.object_funct(3.1415926, 313);
// Problem 1:
Wrapper<&object::object_funct> functor2;
// How to express this below
// functor2(3, 1415926, 313);
object.exec(2.718281, 121);
return 0;
}
源代码 2(不编译)
template <auto F>
struct Wrap;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrap<F> {
auto operator()(Args... args) {
return F(args...);
}
};
struct foo {
int bar(float) {
return 1; };
};
int main() {
foo x;
Wrap<&x::bar> f;
f(3.14159265);
return 0;
}
既然您希望Wrapper
通过模板参数包装成员函数指针,您必须知道如何调用成员函数指针。通常我们使用(obj.*mfptr)(args...)
或(optr->*mfptr)(args...)
调用成员函数指针,显然对象本身也是调用操作所必需的。所以在 Wrapper::operator()
中,我们不仅需要每个参数,还需要对象。
template <auto F>
struct Wrapper;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrapper<F> {
// it seems you don't take care of the cvref qualifiers, so I won't write all the overloads.
auto operator()(T obj, Args... args) {
return (obj.*F)(args...);
}
auto operator()(T* obj, Args... args) {
return (obj->*F)(args...);
}
};
实际上,成员函数调用与将对象作为第一个参数的函数调用相似(而不是等于)。所以你必须这样称呼它:
Wrapper<&foo::bar> f;
f(foo{}, 3.14);
编辑:
现在您还希望包装实例,Wrapper
必须使用实例构造:
template <auto F>
struct Wrapper;
template <typename T, typename R, typename ... Args, R(T::* F)(Args...)>
struct Wrapper<F> {
// I also omit the overloads of pass by reference semantics.
Wrapper(T obj) :instance(std::move(obj)){}
auto operator()(Args... args) {
return (instance.*F)(args...);
}
private:
T instance;
};
int main(){
foo x;
Wrapper<&foo::bar> f{x};
f(3.14);
}