I'm using policy-based design, and I have several policies implementation (that use same interface), but one of the policies needs a different number of args for construction.
So i've used in my class variadic template arguments (typename... InitArgs
)
and I forward them using std::forward
to contructor of policy type.
example:
class Policy1 : public PolicyBase
{
Policy1(int arg1, std::string arg2);
}
class Policy2 : public PolicyBase
{
Policy2(int arg1);
}
template<typename T>
concept PolicyConept = std::is_base_of<PolicyBase, T>::value;
template<PolicyConept T = Policy1, typename... InitArgs>
class PolicyManager
{
public:
PolicyManager(InitArgs... args)
{
_policyState = std::make_unique<T>(std::forward<InitArgs>(args)...);
}
private:
std::unique_ptr<T> _policyState;
}
int main()
{
auto policy1 = std::make_unique<PolicyManager<Policy1>>(1,"2");
auto policy2 = std::make_unique<PolicyManager<Policy2>>(1);
}
I'm looking for a way to use concepts (introduced in C 20), that can perform compile-time check, to ensure the number of arguments provide is enough to build from them the given type.
so would expect the following code to fail at compile time:
int main()
{
auto policy1 = std::make_unique<PolicyManager<Policy1>>(1); // missing argument
}
I was attempting to use the concept std::constructible_from
to accomplish that,
but I'm not sure how the syntax would apply for args...
.
Would appreciate the help
CodePudding user response:
You need to put a constraint on the constructor.
template <typename... Args>
PolicyManager(Args&&... args) requires std::constructible_from<T, Args&&...>
Note also that the Args
template parameter pack should be on the constructor to ensure the arguments are correctly forwarded.