接受一组对象类型的所有组合可能性作为在C ++中起作用的参数

问题描述 投票:2回答:1

给出三个不同的空structsABC,我想让函数foo接受这三个参数中任意数量的任意组合,例如:

struct A {};
struct B {};
struct C {};

// Foo has a required parameter that must be the first one given. Anything else is optional.

foo(1);
foo(1, A{});
foo(1, B{});
foo(1, B{}, A{});
foo(1, A{}, C{}, B{});

我认为可变参数模板和函数重载在这种情况下会有所帮助,所以这是我尝试过的事情:

struct A {};
struct B {};
struct C {};

template <typename... ExtraParams>
void foo(int x, ExtraParams&&...)
{
  std::cout << "x = " << x;
}

template <typename... ExtraParams>
void foo(int x, A&&, ExtraParams&&... extra)
{
  foo(x, extra...);
  std::cout << " with A";
}

template <typename... ExtraParams>
void foo(int x, B&&, ExtraParams&&... extra)
{
  foo(x, extra...);
  std::cout << " with B";
}

// same for C

但是,当调用f(2, A{}, B{})时,仅x = 2 with A被打印。我想我无法理解为什么这行不通,但是我不确定我应该如何实际处理这种情况。

EDIT我针对已知类型使用过的右值引用对代码进行了测试,例如:

template <typename... ExtraParams>
void foo(int x, A&&, ExtraParams&&... extra)
{
  foo(x, extra...);
  std::cout << " with A";
}

这将产生我提到的确切行为(尽管我不知道为什么)。

c++ c++17 variadic-templates variadic-functions
1个回答
0
投票

问题是,当您将参数传递给foo的另一个重载作为foo(x, extra...);时,它们是左值,然后无法绑定到右值引用,例如A&&B&&

您应该使用std::forward,例如

foo(x, std::forward<ExtraParams>(extra)...);

LIVE

© www.soinside.com 2019 - 2024. All rights reserved.