Reputation: 431
I need to pass a templated function to a function.
Until now I haven't found any great advices on google. This is what I tried:
#include <iostream>
#include <sstream>
using namespace std;
struct event {
bool signal;
};
template<typename T>
void out_stream(T &stream, event &evt) {
stream << evt.signal;
}
template <typename F>
void doOperation(F f)
{
event test;
test.signal = 0;
stringstream ss;
f(ss, test);
}
int main() {
doOperation(out_stream);
return 0;
}
And that's the error the compiler gives me:
main.cc:27:3: error: no matching function for call to 'doOperation'
doOperation(out_stream);
^~~~~~~~~~~
main.cc:16:6: note: candidate template ignored: couldn't infer template argument 'F'
void doOperation(F f)
^
1 error generated.
Some (I hope) useful information about my g++ compiler setup:
Thank you in advance :)
Upvotes: 0
Views: 53
Reputation: 8054
For this particular case, you could help the compiler deduce T
by calling doOperation
with out_stream<std::stringstream>
.
Also, within doOperation
, you need to use f
instead of F
.
#include <iomanip> // boolalpha
#include <iostream> // cout
#include <sstream> // stringstream
struct event {
bool signal{};
};
template<typename T>
void out_stream(T& stream, const event& evt) {
stream << std::boolalpha << evt.signal;
}
template <typename F>
void doOperation(F&& f) {
std::stringstream ss{};
f(ss, event{true});
std::cout << ss.str() << "\n";
}
int main() {
doOperation(out_stream<std::stringstream>);
}
// Outputs:
//
// true
As suggested in the comments though, other options you have instead of passing an instantiation of a function template are:
out_stream
to accept a std::ostream&
.#include <iomanip> // boolalpha
#include <iostream> // cout
#include <sstream> // stringstream
struct event {
bool signal{};
};
void out_stream1(std::ostream& stream, const event& evt) {
stream << std::boolalpha << evt.signal;
}
template <typename T>
void out_stream2(T& stream, const event& evt) {
stream << std::boolalpha << evt.signal;
}
template <typename F>
void doOperation(F&& f) {
std::stringstream ss{};
f(ss, event{true});
std::cout << ss.str() << "\n";
}
int main() {
doOperation(out_stream1);
doOperation([](auto& stream, const auto& evt) { out_stream2(stream, evt); });
}
// Outputs:
//
// true
// true
Notice also there are no templated functions, but function templates. out_stream
is a function template and needs to be instantiated with a given type, e.g. out_stream<std::stringstream>
, to become a function. In the call doOperation(out_stream);
, the compiler is unable to deduce the type to instantiate out_stream
with.
Upvotes: 1