简体   繁体   English

C++ 17:如何使用参数包来明确function中参数的顺序,都是相同的类型

[英]C++ 17: How to use parameter packs to clarify the order of parameters in a function which all have the same type

I'm using C++ 17 and want to use template parameters to specify the ordering of the function arguments which all have the same type.我正在使用 C++ 17 并希望使用模板参数来指定 function arguments 的顺序,它们都具有相同的类型。 The function has a varying number of arguments and the sorting of these arguments varies too. function 有不同数量的 arguments,这些 arguments 的排序也不同。

I have tried to use the following (simplified) code to which uses parameter packs to implement this.我尝试使用以下(简化的)代码来使用参数包来实现它。

  • The struct TheInner is the type used for all function arguments.结构TheInner是用于所有 function arguments 的类型。
  • The Outer structs are used to specify the order of the passed parameters to the function. Outer结构用于指定传递给 function 的参数的顺序。
// In .h file
struct TheInner {};
 
template<typename T> struct Outer
{
  using Inner = T;
};

struct OuterA : Outer<TheInner> {};
struct OuterB : Outer<TheInner> {};

template<class... Outers> void Method(Outers::Inner... inners);
template<> void Method<OuterA, OuterA, OuterB>(TheInner a, TheInner a2, TheInner b);
template<> void Method<OuterA, OuterB, OuterA>(TheInner a, TheInner b, TheInner a2);

// In .cpp file
template<> void Method<OuterA, OuterA, OuterB>(TheInner a, TheInner a2, TheInner b)
{
  ...
}

template<> void Method<OuterA, OuterB, OuterA>(TheInner a, TheInner b, TheInner a2)
{
  ...
}

int main(int argc, char** argv)
{
  Method<OuterA, OuterB, OuterA>(TheInner(), TheInner(), TheInner());
}

This currently results in the following error message on GCC:目前,这会导致 GCC 出现以下错误消息:

main.cpp:15:32: error: variable or field 'Method' declared void
   15 | template<class... Outers> void Method(Outers::Inner... inners);
      |                                ^~~~~~
main.cpp:15:55: error: expected ')' before 'inners'
   15 | template<class... Outers> void Method(Outers::Inner... inners);
      |                                      ~                ^~~~~~~
      |                                                       )
main.cpp:17:23: error: expected initializer before '<' token
   17 | template<> void Method<OuterA, OuterA, OuterB>(TheInner a, TheInner a2, TheInner b)
      |                       ^

I have now discovered (after multiple hours) that I was simply missing a typename keyword before the Outers::Inner type.我现在发现(几个小时后)我只是在Outers::Inner类型之前缺少一个typename关键字。

A functional code is attached below in the hope that it might help somebody in the future:下面附上功能代码,希望对以后的人有所帮助:

// Example program
// In .hpp file
#include <iostream>
#include <string>

struct TheInner {};

template<typename T> struct Outer
{
    using Inner = T;
};

struct OuterA : Outer<TheInner> {};
struct OuterB : Outer<TheInner> {};

template<class... Outers> void Method(typename Outers::Inner... inners);
template<> void Method<OuterA, OuterA, OuterB>(TheInner a, TheInner a2, TheInner b);
template<> void Method<OuterA, OuterB, OuterA>(TheInner a, TheInner b, TheInner a2);

// In .cpp file
// #include <iostream>
// #include <string>

template<> void Method<OuterA, OuterA, OuterB>(TheInner a, TheInner a2, TheInner b)
{
    std::cout << "A" << std::endl;
}

template<> void Method<OuterA, OuterB, OuterA>(TheInner a, TheInner b, TheInner a2)
{
    std::cout << "B" << std::endl;
}

int main()
{
    Method<OuterA, OuterB, OuterA>(TheInner(), TheInner(), TheInner()); // Prints B
    Method<OuterA, OuterA, OuterB>(TheInner(), TheInner(), TheInner()); // Prints A

    // Unimplemented methods:

    // error: too many arguments to function 'void Method(typename Outers::Inner ...) [with Outers = {OuterA, OuterA}]'
    // Method<OuterA, OuterA>(TheInner(), TheInner(), TheInner());

    // undefined reference to `void Method<OuterA, OuterA>(OuterA::Inner, OuterA::Inner)'
    // Method<OuterA, OuterA>(TheInner(), TheInner());
}

The output of the program is:程序的output为:

B
A

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM