1
我需要将异步函数调用转换为同步函数调用。有很多这样的功能,所以我想使用模板进行转换。下面是一个简化程序的样子:使用可变参数模板调用成员函数
#include <functional>
#include <future>
#include <iostream>
using namespace std;
using CallBack = function<void (int)>;
class C {
template<typename... Ts>
int InvokeAsync(void (C::*async)(Ts..., CallBack), Ts... args) {
promise<int> p;
auto cb = [&p](int r) { p.set_value(r); };
async(args..., cb);
auto f = p.get_future();
f.wait();
return f.get();
}
public:
void Async(int x, int y, CallBack cb) {
cb(x + y);
}
int Sync(int x, int y) {
return InvokeAsync(&C::Async, x, y);
}
void Async(int x, CallBack cb) {
cb(x);
}
int Sync(int x) {
return InvokeAsync(&C::Async, x);
}
};
该程序不编译。
GCC
$ g++ --version
g++ (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -c -std=c++14 -o x.o x.cc
x.cc: In member function ‘int C::Sync(int, int)’:
x.cc:24:43: error: no matching function for call to ‘C::InvokeAsync(<unresolved overloaded function type>, int&, int&)’
return InvokeAsync(&C::Async, x, y);
^
x.cc:11:9: note: candidate: template<class ... Ts> int C::InvokeAsync(void (C::*)(Ts ..., CallBack), Ts ...)
int InvokeAsync(void (C::*async)(Ts..., CallBack), Ts... args) {
^
x.cc:11:9: note: template argument deduction/substitution failed:
x.cc:24:43: note: mismatched types ‘CallBack {aka std::function<void(int)>}’ and ‘int’
return InvokeAsync(&C::Async, x, y);
^
x.cc:24:43: note: mismatched types ‘CallBack {aka std::function<void(int)>}’ and ‘int’
x.cc:24:43: note: could not resolve address from overloaded function ‘&((C*)this)->*C::Async’
x.cc: In member function ‘int C::Sync(int)’:
x.cc:30:40: error: no matching function for call to ‘C::InvokeAsync(<unresolved overloaded function type>, int&)’
return InvokeAsync(&C::Async, x);
^
x.cc:11:9: note: candidate: template<class ... Ts> int C::InvokeAsync(void (C::*)(Ts ..., CallBack), Ts ...)
int InvokeAsync(void (C::*async)(Ts..., CallBack), Ts... args) {
^
x.cc:11:9: note: template argument deduction/substitution failed:
x.cc:30:40: note: mismatched types ‘CallBack {aka std::function<void(int)>}’ and ‘int’
return InvokeAsync(&C::Async, x);
^
x.cc:30:40: note: mismatched types ‘CallBack {aka std::function<void(int)>}’ and ‘int’
x.cc:30:40: note: could not resolve address from overloaded function ‘&((C*)this)->*C::Async’
铛
$ clang++ --version
clang version 3.7.1 (tags/RELEASE_371/final)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
$ clang++ -c -std=c++14 -o x.o x.cc
x.cc:24:16: error: no matching member function for call to 'InvokeAsync'
return InvokeAsync(&C::Async, x, y);
^~~~~~~~~~~
x.cc:11:9: note: candidate template ignored: substitution failure [with Ts = <int, int>]
int InvokeAsync(void (C::*async)(Ts..., CallBack), Ts... args) {
^
x.cc:14:9: error: called object type 'void (C::*)(int, CallBack)' is not a function or function pointer
async(args..., cb);
^~~~~
x.cc:30:16: note: in instantiation of function template specialization 'C::InvokeAsync<int>' requested here
return InvokeAsync(&C::Async, x);
^
2 errors generated.
,该怎么办错了:这里是由gcc和铛,分别产生的错误?
你试过了吗?重载解析如何在两个版本的Async之间进行选择? –
@ n.m。公平点,我没有。这需要在呼叫站点进行明确的演员表演,这并不比第一次通过回调更好。 –