How do you decode template related errors?

Hi hi :slight_smile: I need your expertise again. This code:

    listeners.push(ofEvents().update.newListener(this, [&]() {
        std::cout << ofGetFrameNum() << std::endl;
    }));

produces this error:

In file included from /x/src/openFrameworks/libs/openFrameworks/events/ofEventUtils.h:4,
                 from /x/src/openFrameworks/libs/openFrameworks/events/ofEvents.h:4,
                 from /x/src/openFrameworks/libs/openFrameworks/types/ofParameter.h:3,
                 from /x/src/openFrameworks/addons/ofxGui/src/ofxToggle.h:3,
                 from /x/src/openFrameworks/addons/ofxGui/src/ofxGui.h:3,
                 from /x/Desktop/edu/src/openframeworks/cerealInotify/src/config.h:6,
                 from /x/Desktop/edu/src/openframeworks/cerealInotify/src/config.cpp:1:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h: In instantiation of ‘std::unique_ptr<of::priv::AbstractEventToken> ofEvent<T, Mutex>::newListener(TObj*, TMethod, int) [with TObj = Config; TMethod = Config::Config(std::string)::<lambda()>; T = ofEventArgs; Mutex = std::recursive_mutex]’:
/x/Desktop/edu/src/openframeworks/cerealInotify/src/config.cpp:18:6:   required from here
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:534:21: error: no matching function for call to ‘ofEvent<ofEventArgs>::make_function(Config*&, Config::Config(std::string)::<lambda()>&, int&)’
  534 |   return addFunction(make_function(listener,method,priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:476:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, bool (TObj::*)(T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  476 |  FunctionPtr make_function(TObj * listener, bool (TObj::*method)(T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:476:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:534:21: note:   mismatched types ‘bool (TObj::*)(ofEventArgs&)’ and ‘Config::Config(std::string)::<lambda()>’
  534 |   return addFunction(make_function(listener,method,priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:481:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, void (TObj::*)(T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  481 |  FunctionPtr make_function(TObj * listener, void (TObj::*method)(T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:481:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:534:21: note:   mismatched types ‘void (TObj::*)(ofEventArgs&)’ and ‘Config::Config(std::string)::<lambda()>’
  534 |   return addFunction(make_function(listener,method,priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:489:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, bool (TObj::*)(const void*, T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  489 |  FunctionPtr make_function(TObj * listener, bool (TObj::*method)(const void*, T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:489:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:534:21: note:   mismatched types ‘bool (TObj::*)(const void*, ofEventArgs&)’ and ‘Config::Config(std::string)::<lambda()>’
  534 |   return addFunction(make_function(listener,method,priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:494:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, void (TObj::*)(const void*, T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  494 |  FunctionPtr make_function(TObj * listener, void (TObj::*method)(const void*, T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:494:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:534:21: note:   mismatched types ‘void (TObj::*)(const void*, ofEventArgs&)’ and ‘Config::Config(std::string)::<lambda()>’
  534 |   return addFunction(make_function(listener,method,priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:511:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<bool(T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  511 |  FunctionPtr make_function(std::function<bool(T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:511:14: note:   candidate expects 2 arguments, 3 provided
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:515:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<bool(const void*, T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  515 |  FunctionPtr make_function(std::function<bool(const void*, T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:515:14: note:   candidate expects 2 arguments, 3 provided
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:519:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<void(T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  519 |  FunctionPtr make_function(std::function<void(T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:519:14: note:   candidate expects 2 arguments, 3 provided
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:523:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<void(const void*, T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  523 |  FunctionPtr make_function(std::function<void(const void*, T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:523:14: note:   candidate expects 2 arguments, 3 provided
Process failed with exit code 1.

Unfortunately in QtCreator it’s all red text on black, no formatting, very hard to read.

How do you go about figuring out what it means? What is the useful part in this error message to help me fix the problem?

when using non member functions as listeners, including lambdas, you don’t need to pass the listener object as they don’t belong to any. so the correct syntax would be:

listeners.push(ofEvents().update.newListener([&]() {
        std::cout << ofGetFrameNum() << std::endl;
    }));

or:

listeners.push(ofEvents().update.newListener([this]() {
        std::cout << ofGetFrameNum() << std::endl;
    }));

where you capture this instead of the scope by reference. in the first you can access the scope of the current function from the lambda which is not usually what you want and might crash the program if you accidentally access a variable in the current function that for example has the same name as a member variable

1 Like

I had tried those options earlier and I get varations of the same poem:

In file included from /x/src/openFrameworks/libs/openFrameworks/events/ofEventUtils.h:4,
                 from /x/src/openFrameworks/libs/openFrameworks/events/ofEvents.h:4,
                 from /x/src/openFrameworks/libs/openFrameworks/types/ofParameter.h:3,
                 from /x/src/openFrameworks/addons/ofxGui/src/ofxToggle.h:3,
                 from /x/src/openFrameworks/addons/ofxGui/src/ofxGui.h:3,
                 from /x/Desktop/edu/src/openframeworks/cerealInotify/src/config.h:6,
                 from /x/Desktop/edu/src/openframeworks/cerealInotify/src/config.cpp:1:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h: In instantiation of ‘std::unique_ptr<of::priv::AbstractEventToken> ofEvent<T, Mutex>::newListener(TFunction, int) [with TFunction = Config::Config(std::string)::<lambda()>; T = ofEventArgs; Mutex = std::recursive_mutex]’:
/x/Desktop/edu/src/openframeworks/cerealInotify/src/config.cpp:18:6:   required from here
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:549:21: error: no matching function for call to ‘ofEvent<ofEventArgs>::make_function(std::function<void()>, int&)’
  549 |   return addFunction(make_function(std::function<typename of::priv::callable_traits<TFunction>::function_type>(function), priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:476:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, bool (TObj::*)(T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  476 |  FunctionPtr make_function(TObj * listener, bool (TObj::*method)(T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:476:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:549:21: note:   mismatched types ‘TObj*’ and ‘std::function<void()>’
  549 |   return addFunction(make_function(std::function<typename of::priv::callable_traits<TFunction>::function_type>(function), priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:481:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, void (TObj::*)(T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  481 |  FunctionPtr make_function(TObj * listener, void (TObj::*method)(T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:481:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:549:21: note:   mismatched types ‘TObj*’ and ‘std::function<void()>’
  549 |   return addFunction(make_function(std::function<typename of::priv::callable_traits<TFunction>::function_type>(function), priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:489:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, bool (TObj::*)(const void*, T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  489 |  FunctionPtr make_function(TObj * listener, bool (TObj::*method)(const void*, T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:489:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:549:21: note:   mismatched types ‘TObj*’ and ‘std::function<void()>’
  549 |   return addFunction(make_function(std::function<typename of::priv::callable_traits<TFunction>::function_type>(function), priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:494:14: note: candidate: ‘template<class TObj> ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(TObj*, void (TObj::*)(const void*, T&), int) [with TObj = TObj; T = ofEventArgs; Mutex = std::recursive_mutex]’
  494 |  FunctionPtr make_function(TObj * listener, void (TObj::*method)(const void*, T&), int priority){
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:494:14: note:   template argument deduction/substitution failed:
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:549:21: note:   mismatched types ‘TObj*’ and ‘std::function<void()>’
  549 |   return addFunction(make_function(std::function<typename of::priv::callable_traits<TFunction>::function_type>(function), priority));
      |          ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:511:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<bool(T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  511 |  FunctionPtr make_function(std::function<bool(T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:511:52: note:   no known conversion for argument 1 from ‘function<void()>’ to ‘function<bool(ofEventArgs&)>’
  511 |  FunctionPtr make_function(std::function<bool(T&)> f, int priority) {
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~^
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:515:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<bool(const void*, T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  515 |  FunctionPtr make_function(std::function<bool(const void*, T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:515:65: note:   no known conversion for argument 1 from ‘function<void()>’ to ‘function<bool(const void*, ofEventArgs&)>’
  515 |  FunctionPtr make_function(std::function<bool(const void*, T&)> f, int priority) {
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:519:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<void(T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  519 |  FunctionPtr make_function(std::function<void(T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:519:52: note:   no known conversion for argument 1 from ‘function<void()>’ to ‘function<void(ofEventArgs&)>’
  519 |  FunctionPtr make_function(std::function<void(T&)> f, int priority) {
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~^
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:523:14: note: candidate: ‘ofEvent<T, Mutex>::FunctionPtr ofEvent<T, Mutex>::make_function(std::function<void(const void*, T&)>, int) [with T = ofEventArgs; Mutex = std::recursive_mutex; ofEvent<T, Mutex>::FunctionPtr = std::shared_ptr<of::priv::Function<ofEventArgs, std::recursive_mutex> >]’
  523 |  FunctionPtr make_function(std::function<void(const void*, T&)> f, int priority) {
      |              ^~~~~~~~~~~~~
/x/src/openFrameworks/libs/openFrameworks/events/ofEvent.h:523:65: note:   no known conversion for argument 1 from ‘function<void()>’ to ‘function<void(const void*, ofEventArgs&)>’
  523 |  FunctionPtr make_function(std::function<void(const void*, T&)> f, int priority) {
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

I tried many variations and all of them failed, therefore my main question is not how to fix this specific problem, but if it is possible by looking at the error to figure out how to fix it. Or maybe the message is not that useful and you just need to build an intuition of what works?

ps. In the same file I use this which works fine:

    listeners.push(gui->buttonLoadFrom.newListener([this]() {
        ofFileDialogResult result = ofSystemLoadDialog("Load file");
        if(result.bSuccess) {
            string path = result.getPath();
            cfg->load(path);
        }
    }));

So listeners.push works, .newListener works, but just not with ofEvents().xxx for me.

Maybe it’s a bug? If I add these lines to a working project it stops compiling:

// .h
ofEventListeners listeners;

// .cpp
listeners.push(ofEvents().update.newListener([this]() {
  std::cout << ofGetFrameNum() << std::endl;
}));

Have you tryied:

// .h
ofEventListeners listeners;

// .cpp
listeners.push(ofEvents().update.newListener([this](ofEventArgs &args) {
  std::cout << ofGetFrameNum() << std::endl;
}));
1 Like

(ofEventArgs &args) does work. Thank you :slight_smile:

Can you @EduardFrigola comment on the error message? What do you do when you see such message? Which lines do you look at? Does it tell you which arguments it’s not happy with?

Based on experience, when make_function in a lambda does not find a candidate, it means that you have no function to call with those arguments.
In this case you tried to call ofEvent::update without arguments, and that does not exist. And the templated make_function is not finding a way to resolve for that specific function with those specific arguments.
I think missing the return value, or returning a wrong one will end to the same compiler error.

That is what i think when I see these, not what a nice cpp book will answer :stuck_out_tongue:
Correct me if I’m wrong…

1 Like

Thank you, very helpful :slight_smile: I was copying code from

Maybe the last example should be corrected to match this needed argument? Also there are mentions of mouseMovedEvent and mousePressedEvent. I think the Event part should be removed.

This tries to explain why error messages can be so verbose: