This question is similar to this C++ - Multiple parameter packs for variadic function, but specifically for structs.
The following compiles and runs fine (taken from the linked question).
template <typename... TDependencies, typename ...TArgs>
void fooFunction(TArgs...args) {
std::cout << "TDependecies list:" << std::endl;
((std::cout << "- " << typeid(TDependencies).name() << std::endl), ...);
std::cout << "TArgs list:" << std::endl;
((std::cout << "- " << typeid(TArgs).name() << std::endl), ...);
}
int main()
{
fooFunction<std::string, short, int, long, long long>(0, 1l, 2ll);
}
as the type deduction will be successful based on the arguments provided to fooFunction.
My question is, why does the deduction not work with a struct like this?
template <typename... TDependencies, typename ...TArgs>
struct fooStruct {
fooStruct(TArgs...args) {
std::cout << "TDependecies list:" << std::endl;
((std::cout << "- " << typeid(TDependencies).name() << std::endl), ...);
std::cout << "TArgs list:" << std::endl;
((std::cout << "- " << typeid(TArgs).name() << std::endl), ...);
}
};
int main()
{
fooStruct<std::string, short, int, long, long long> s(0, 1l, 2ll);
}
The compiler error is parameter pack ‘TDependencies’ must be at the end of the template parameter list.
I've tried adding a user deduction guide like below, but that gives the error trailing return type ‘<type error>’ of deduction guide is not a specialization of ‘fooStruct<<declaration error>, TArgs>’
template <typename... TDependencies, typename ...TArgs>
fooStruct(const TArgs...) -> fooStruct<TDependencies..., TArgs...>;
is there any way to accomplish this?
For context the ultimate goal is to have something like this to zip the two variadic packs together.
template <typename T1, typename T2>
struct base {
};
template <typename... T1, typename ...T2>
struct child : base<T1, T2>... {
child(T2... args) {}
};
child here will use T2 but base will use T1 and T2.
The error is clear: the standard forbids it.
To solve your problem you need a factory function. And you know how to write that factory function.
Partial CTAD is banned by the standard. It was complex and not clear so they nixed it. So there is no way to deduce half of the arguments, other than a factory function.
using
to delimit arguments into two packs.