Skip to content

Wrong single_service when it should be service #126

@JassJam

Description

@JassJam

Describe the bug
Attempting to use container.service<> on a service that implements autowire_service, will result in copy of the object rather than move since its using single_service instead of service.

template<typename T, typename Map = map<>, std::size_t max_dependencies = detail::default_max_dependency>
using autowire_service = single_service<T, kgr::mapped_autowire<Map, max_dependencies>>;
template<typename T, typename Map = map<>, std::size_t max_dependencies = detail::default_max_dependency>
using autowire_single_service = single_service<T, kgr::mapped_autowire<Map, max_dependencies>>;

To Reproduce
1- Create main.cpp with the following content:

struct Noisy
{
    std::string Name;

    Noisy(const char* Name) :
        Name(Name)
    {
        printf("Noisy::Noisy(%s);\n", Name);
    }

    Noisy(const Noisy& o) :
        Name(o.Name)
    {
        printf("Noisy::Noisy(const Noisy&=%s);\n", Name.c_str());
    }

    Noisy(Noisy&& o) :
        Name(std::move(o.Name))
    {
        printf("Noisy::Noisy(Noisy&&=%s);\n", Name.c_str());
    }

    Noisy& operator=(const Noisy& o)
    {
        Name = o.Name;
        printf("Noisy& Noisy::operator=(const Noisy&=%s);\n", Name.c_str());
        return *this;
    }

    Noisy& operator=(Noisy&& o)
    {
        Name = o.Name;
        printf("Noisy& Noisy::operator=(Noisy&&=%s);\n", Name.c_str());
        return *this;
    }

    ~Noisy()
    {
        printf("Noisy::~Noisy(%s);\n", Name.c_str());
    }
};

struct System1 : Noisy
{
public:
    System1() :
        Noisy("System1")
    {
    }
};

struct System2 : Noisy
{
    System2() :
        Noisy("System2")
    {
    }
};

template<typename T, typename Map = kgr::map<>, std::size_t max_dependencies = kgr::detail::default_max_dependency>
using correct_autowire_service = kgr::service<T, kgr::mapped_autowire<Map, max_dependencies>>;

struct Subsystem1 : correct_autowire_service<System1>
{
};

struct Subsystem2 : kgr::autowire_service<System2>
{
};

auto service_map(System1 const&) -> Subsystem1;
auto service_map(System2 const&) -> Subsystem2;

int main()
{
    kgr::container container;

    auto a = container.service<Subsystem1>();
    auto b = container.service<Subsystem2>();

    // auto& a0 = container.service<Subsystem1>(); // triggers compilation error (correct)
    // auto& b1 = container.service<Subsystem2>(); // should not compile

    return 0;
}

Expected behavior
The program should not make copies of the service but instead move it around
the output for the previous sample:

Noisy::Noisy(System1);
Noisy::Noisy(Noisy&&=System1);
Noisy::~Noisy();
Noisy::Noisy(Noisy&&=System1);
Noisy::~Noisy();
Noisy::Noisy(System2);
Noisy::Noisy(const Noisy&=System2);
Noisy::~Noisy(System2);
Noisy::~Noisy(System1);
Noisy::~Noisy(System2);

Desktop (please complete the following information):

  • OS: Windows
  • Compiler: MSVC
  • Version: 19.39.33523

Additional context
Another note i've noticed is that it moves the object two times instead of once.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions