Home > Software engineering >  template std::boost function given to a thread invalid static_cast
template std::boost function given to a thread invalid static_cast

Time:07-02

I am writing an util class to facilitate thread management into ROS environment. I would like to pass a callback ROS function coded with the boost lib lambda expression style in argument to my thread handler object (TriggeredProcess class). Here is my code :

my code

#include <boost/function.hpp>
#include <boost/thread.hpp>

namespace alongside {
    class TriggeredProcess {
    public:
        template<typename Message> 
        TriggeredProcess(
            const boost::function<void (Message const&)>& callback
        ) {
            boost::thread triggred_process(
                static_cast<void(*)(
                    const boost::function<void (Message const&)>&s
                )>(&run), 
                callback
            );
        }

    private:
        template<typename Message>
        void run(
            const boost::function<void (Message const&)>& callback
        ) {
            //placeholder
        }
    };
}


int main(int argc, char** argv)
{
    /** 
     * @brief Originally roscpp @p std_msg::Bool type is used, 
     * but can be any kind of msg type.
     * Here to avoid ros deps I use SL @p bool type, 
     * with the same kind of error
     */
    boost::function<void (const bool&)> callback = [&] (const bool& msg) {
        //placeholder
    };

    alongside::TriggeredProcess a(callback);
}

my error message

error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘void (*)(const boost::function<void(const bool&)>&)’
   14 |                 static_cast<void(*)(
      |                 ^~~~~~~~~~~~~~~~~~~~
   15 |                     const boost::function<void (Message const&)>&s
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   16 |                 )>(&run),
      |                 ~~~~~~~~

my dev env specs

Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)

In the constructor of TriggeredProcess, it seems to dislike boost functions with template parameters passed in a static_cast used as suggested here.

Did you have any idea of another implementation to pass template argumented functions to a boost::thread ? Or what is wrong in my implementation please ? Thanks in advance !!

CodePudding user response:

I think the issue is caused by two core mistakes:

  • &run, which takes the address of a template
  • calling a nonstatic memberfunction without this

You static_cast the address of the template to a different type (probably in order to resolve the type ambiguity), but that is what you'd do with an actually overloaded function. Instead, use &run<MessageType>. Note that the compiler can determine the template parameters automatically in most cases, in particular when they are the same as the passed arguments, but you can always specify them explicitly. In this case, I'd even say it is cleaner.

The second thing is that you pass the memberfunction address and parameters for its call to the thread constructor. A memberfunction in C is not bound to an object though, but it absolutely needs an object for being called. The object is most probably this, but if you don't need an instance data, you can also make the memberfunction static. However, all this is way too complicated IMHO. Instead, just use a lambda.

Fixed class code:

class TriggeredProcess {
public:
    template<typename Message> 
    TriggeredProcess(
        const boost::function<void (Message const&)>& callback
    ) {
        boost::thread triggred_process([&] {
            this->run(callback);
        });
    }

private:
    template<typename Message>
    void run(
        const boost::function<void (Message const&)>& callback
    ) {
        //placeholder
    }
};

Just one final note: I think you're reinventing https://en.cppreference.com/w/cpp/thread/async a bit here, maybe scrapping that approach and using something from the shelf would make your life (and that of the next dev reading the code) more productive.

  • Related