Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpreting C++ variadic template arguments from other variadic template arguments

Tags:

c++

templates

I would appreciate if someone is able to supply me with better terminology for the question as I am struggling to put it into words in the title. Essentially, my problem is I require a struct along the lines of

template <typename... Types>
struct acceptor {

  // ...

  template <
    // assumedly, something needs to go here
  >
  static inline void accept(void) { 
    // ...
  }

  // ...

};

such that I am able to run

int main(void) {
  acceptor<int, int, float>::template accept<0, 1, 0.5f>();
  acceptor<unsigned long, double>::template accept<6UL, -4.6>();

  return 0;
}

Can I please get a definitive answer on whether or not this is possible within the C++ language and if so, how?

I tried

template <
  Types... Values
>
static inline void accept(void) {
 // ...
}

but that just seemingly tried to make essentially a variadic of the first type rather than a single non-type parameter per outer argument. The argument appears to always be wrong number of template arguments (<whatever number of arguments I specified>, should be 1).

It does not appear to be possible in C++20 or any later version from what I can tell and I've had to construct a structural (so it can be used at compile time) tuple type to handle this but it is somewhat ugly and I'd like to avoid using it if possible. Noting that this was being done on an Ubuntu install of gcc.

like image 683
notgapriel Avatar asked May 11 '26 08:05

notgapriel


1 Answers

There seems to be a bug in gcc and MSVC preventing the instantiation of accept using Types... values, but you can work around it by using auto...:

#include <type_traits>

template <class... Types>
struct acceptor {
    template <auto... values>
//            ^^^^^^^
        requires std::conjunction_v<std::is_same<Types, decltype(values)>...>
    static void accept() {
        // use values as you want:
        (..., (std::cout << ' ' << values));
        std::cout << '\n';
    }
};

requires std::conjunction_v<std::is_same<Types, decltype(values)>...> is there to constrain the accepted non-type template parameters to what you supplied in Types.

Demo

like image 185
Ted Lyngmo Avatar answered May 12 '26 22:05

Ted Lyngmo