Home > Mobile >  how do I forward the templates arguments onto the std::make_unique when creating policy based class?
how do I forward the templates arguments onto the std::make_unique when creating policy based class?

Time:09-25

Lets assume I'm using policy based templates design pattern (see https://en.wikipedia.org/wiki/Modern_C++_Design).

I'm having some issue related to how would I use std::make_shared (or std::make_unique for that matter) for creating new type Bar, that has some optional template arguments.
If I don't want to change default policy, then that's no problem, simple line would work:

auto bar = std::make_unique<Bar>();

However if I want Bar accept different "policy" as template args, how can I pass them into std::make_unique ??

tried the following (with no luck):

auto bar = std::make_unique<Bar<Policy2, Policy3>>();

or:

auto bar = std::make_unique<Bar>(Policy2, Policy3);

Here are some sample code to demonstrate the problem:

// Bar.hpp
template<PolicyConcept1 T = policy1_default, PolicyConcept2 V = policy2_default>
class Bar
{
public:
    Bar();

private:
    // Data Members
    std::unique_ptr<T> _policy1;
    std::unique_ptr<V> _policy2;    
};

// bar.cpp
#include "bar.hpp"

template<PolicyConcept1 T, PolicyConcept2 V>
Bar<T, V>::Bar() :
_policy1{ std::make_unique<T>() },
_policy2{ std::make_unique<V>()}
{

}

// Foo.hpp
template<PolicyConcept1 T = policy1_default, PolicyConcept2 V = policy2_default>
class Foo
{
public:
    Foo();

private:
    // Data Members
    std::unique_ptr<Bar> _bar;  

};

#include "Foo.hpp"


template<PolicyConcept1 T, PolicyConcept2 V>
Foo<T, V>::Foo() :
  // problem is here, how do I change the default policy and forward it into std::make_unique ??
    _bar{ std::make_unique<bar>() }
{

}

The question is inside initializer of Foo CTOR: how do I forward the T & V template arguments onto the std::make_unique ??

appreciate any help :)

CodePudding user response:

Figured this out. It's turns out the syntax:

auto bar = std::make_unique<Bar<Policy2, Policy3>>();

works after all (on C 20, using MSVC v16.10.2).

It requires the following declaration to work:

std::unique_ptr<Bar<T,V>> _bar;

in addition I had to provide on CPP this as well (to avoid linker error):

template class Bar<concrete_policy1, concrete_policy2>;
  • Related