Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Call member function with parameter pack from function with parameter pack

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<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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

<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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading