I need to convert asynchronous function calls into synchronous function calls. There are many such functions, so I want to do the conversion using a template. Here is how a simplified program looks like:
#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);
}
};
This program does not compile. Here are the errors produced by gcc and clang, respectively:
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
$ 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.
What do I do wrong?
Aucun commentaire:
Enregistrer un commentaire