Ary*_*yan 4 c++ templates member-function-pointers function-pointers variadic-templates
我正在尝试为模板类编写一个函数,该函数接受一个参数,该参数是大类私有数据中成员类的函数指针.当您调用该成员时,它会在较小的类上调用该函数.(令人困惑的权利?)为了证明,我在这里有一个非工作的例子:
#include <vector>
#include <iostream>
using namespace std;
template <typename T, typename C>
struct MyClass {
template <typename F, typename... A>
auto call_me(F func, A... args) { // pass in the function we want to call
return (mContainer.*func) (args...); // call the function supplied by
// the parameter on the private member data
}
C mContainer; // this will be private in my actual code
};
int main() {
MyClass<int, std::vector<int> > test;;
cout << test.call_me(&std::vector<int>::size) << endl; // works
test.call_me(&std::vector<int>::insert, test.mContainer.begin(), 4); // doesn't work
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不是我的实际代码,而是我正在尝试做的一个小例子.正如你所看到的,我正在尝试调用size'Private' 的成员函数(我已将它保存在这里用于演示)vector类里面MyClass.这只适用于我没有编译器解压缩的参数,但是当我尝试执行insert函数(其中包含要解压缩的参数)时,编译器会给出一个错误:
.\template.cpp: In function 'int main()':
.\template.cpp:24:71: error: no matching function for call to 'MyClass<int, std::vector<int> >::call_me(<unresolved overloaded function type>, std::vector<int>::iterator, int)'
test.call_me(&std::vector<int>::insert, test.mContainer.begin(), 4);
^
.\template.cpp:10:10: note: candidate: template<class F, class ... A> auto MyClass<T, C>::call_me(F, A ...) [with F = F; A = {A ...}; T = int; C = std::vector<int>]
auto call_me(F func, A... args) { // pass in the function we want to call
^~~~~~~
.\template.cpp:10:10: note: template argument deduction/substitution failed:
.\template.cpp:24:71: note: couldn't deduce template parameter 'F'
test.call_me(&std::vector<int>::insert, test.mContainer.begin(), 4);
Run Code Online (Sandbox Code Playgroud)
这是我在我的实际生产代码中得到的同样的错误,调用variadic函数没有参数来解压缩工作,但如果我给出更多,我得到相同的错误消息.这是我第一次真正尝试使用Variadic模板,因此任何推荐和帮助都将受到赞赏.
这里的问题是insert重载功能.编译器没有尝试解决模板参数推导中你想要的重载,因为它无法知道.您必须将函数强制转换为要使用的重载类型,以便为其提供类型.那看起来像
using insert_func_t = std::vector<int>::iterator(std::vector<int>::*)(std::vector<int>::const_iterator, const int&);
test.call_me(static_cast<insert_func_t>(&std::vector<int>::insert), test.mContainer.begin(), 4);
Run Code Online (Sandbox Code Playgroud)
一般来说是
static_cast<return_type(class_name::*)(function_parameters)>(&class_name::function_name)
Run Code Online (Sandbox Code Playgroud)
另一种选择是稍微改变一下这个功能,并采用一个表达你想做的事情的lambda.那看起来像
template <typename T, typename C>
struct MyClass {
template <typename F, typename... A>
auto call_me(F func, A... args) { // pass in the function we want to call
return func(mContainer, args...); // call the function supplied by
// the parameter on the private member data
}
C mContainer; // this will be private in my actual code
};
int main() {
MyClass<int, std::vector<int> > test;;
test.call_me([](auto& container, auto... args){ container.insert(args...); }, test.mContainer.begin(), 4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75 次 |
| 最近记录: |