首页 > 解决方案 > C++ 17:如何使用参数包来阐明函数中所有具有相同类型的参数的顺序

问题描述

我正在使用 C++ 17 并希望使用模板参数来指定所有具有相同类型的函数参数的顺序。该函数具有不同数量的参数,并且这些参数的排序也各不相同。

我尝试使用以下(简化的)代码来使用参数包来实现这一点。

// 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());
}

这目前会导致 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)
      |                       ^

标签: c++templates

解决方案


我现在发现(几个小时后)我只是typename在类型之前缺少了一个关键字Outers::Inner

下面附上一个功能代码,希望它将来可能对某人有所帮助:

// 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());
}

程序的输出是:

B
A

推荐阅读