给出三个不同的空structs
,A
,B
和C
,我想让函数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";
}
这将产生我提到的确切行为(尽管我不知道为什么)。
问题是,当您将参数传递给foo
的另一个重载作为foo(x, extra...);
时,它们是左值,然后无法绑定到右值引用,例如A&&
和B&&
。
您应该使用std::forward
,例如
foo(x, std::forward<ExtraParams>(extra)...);