visual-c++c++-actor-framework

Compiler Error C2664 when spawning a typed actor


I'm getting a compiler error with the following code, slightly modified from one of the examples provided by the C++ Actor Framework. The error description is:

'void caf::intrusive_ptr_release(caf::ref_counted *)': cannot convert argument 1 from 'caf::typed_actor<caf::typed_mpi<caf::detail::type_list<plus_atom,int,int>,caf::detail::type_list<result_atom,int>,caf::detail::empty_type_list>,caf::typed_mpi<caf::detail::type_list<minus_atom,int,int>,caf::detail::type_list<result_atom,int>,caf::detail::empty_type_list>> ' to 'caf::ref_counted *'   include\caf\intrusive_ptr.hpp   70

Here is the source code (again, modified from a C++ Actor Framework example):

#include "caf/all.hpp"

using namespace caf;

using plus_atom = atom_constant<atom("plus")>;
using minus_atom = atom_constant<atom("minus")>;
using result_atom = atom_constant<atom("result")>;

using calculator_type = typed_actor<replies_to<plus_atom, int, int>::with<result_atom, int>,
                                    replies_to<minus_atom, int, int>::with<result_atom, int>>;

calculator_type::behavior_type typed_calculator(calculator_type::pointer)
{
    return
    {
        [](plus_atom, int x, int y)
        {
            return std::make_tuple(result_atom::value, x + y);
        },
        [](minus_atom, int x, int y)
        {
            return std::make_tuple(result_atom::value, x - y);
        }
    };
}

int main()
{
    spawn_typed<calculator_type>(typed_calculator);
    shutdown();
}

Solution

  • Using the templated spawn_typed call requires that an implementing class be referenced as in the following example:

    #include "caf/all.hpp"
    
    using namespace caf;
    
    using plus_atom = atom_constant<atom("plus")>;
    using minus_atom = atom_constant<atom("minus")>;
    using result_atom = atom_constant<atom("result")>;
    
    using calculator_type = typed_actor<replies_to<plus_atom, int, int>::with<result_atom, int>,
                                        replies_to<minus_atom, int, int>::with<result_atom, int>>;
    
    class typed_calculator_class : public calculator_type::base
    {
    protected:
        behavior_type make_behavior() override
        {
            return
            {
                [](plus_atom, int x, int y)
                {
                    return std::make_tuple(result_atom::value, x + y);
                },
                [](minus_atom, int x, int y)
                {
                    return std::make_tuple(result_atom::value, x - y);
                }
            };
        }
    };
    
    int main()
    {
        spawn_typed<typed_calculator_class>();
        shutdown();
    }
    

    Alternatively, to use a non-class based typed actor, simply omit the templating argument from the original code:

    spawn_typed(typed_calculator);