Let's say I have a struct with a member function with parameter pack:
template <typename T>
struct MyStruct {
int my_int;
template <auto... params>
auto DoSomething() {
return InternalFunction<T, params...>();
}
};
InternalFunction
should not matter that much, but just to make things compile, let's say it's this:
template <typename T>
T InternalFunction() {
return T();
}
template <typename T, auto... params>
auto InternalFunction() {
return InternalFunction<params...>();
}
I would like to call this member function from another function that takes the same parameter pack:
template<typename T, auto... params>
auto DoSomethingFromSomewhereElse(){
MyStruct<T> mystruct;
return mystruct.DoSomething<params...>(); // Unfortunately this doesn't work.
}
The compiler complains about unexpanded parameter pack. How do I do this?
<source>: In function 'auto DoSomethingFromSomewhereElse()':
<source>:24:19: warning: expected 'template' keyword before dependent template name [-Wmissing-template-keyword]
24 | return mystruct.DoSomething<params...>(); // Unfortunately this doesn't work.
| ^~~~~~~~~~~
| template
<source>:24:30: error: parameter packs not expanded with '...':
24 | return mystruct.DoSomething<params...>(); // Unfortunately this doesn't work.
| ~~~~~~~~~~~~~~~~~~~~^~~~~~~
Just add template to resolve dependent name:
template<typename T, auto... params>
auto DoSomethingFromSomewhereElse(){
MyStruct<T> mystruct;
return mystruct.template DoSomething<params...>(); // this works
}
UPD:
The reason why the code is not compiled:
Experession
mystruct.DoSomething<params...>();
Can be threated as:
(mystruct.DoSomething < params...) > ();
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
// comparasion operator
if MyStruct<T>
declared like this:
template<typename T>
struct MyStruct {
T DoSomething;
};
Because the compiler cannot know for sure that DoSomething is a function and not a variable, due to the fact that the name depends on MyStruct, which depends on T.
Therefore, you need to explicitly specify this, indicating that DoSomething is exactly the template function call, rather than accessing a variable and then doing a comparasion