函数参数的嵌套模板参数和 cv- 和 ref- 限定符

Nested template parameters and cv- and ref- qualifiers for function arguments

我有一个看起来有点像这样的函数:

template <typename... A, typename... B>
void foo(Foo<A...>&, Foo<B...>&);

问题是,我希望它在两个 const/non-const 版本中为两个参数接受任何类型的引用 (lvalue/rvalue)。

这已经是16种组合了,显然手动写太多了

我能看到的唯一解决方案是删除嵌套类型参数:

template <typename X, typename Y>
void foo(X&&, Y&&);
// + some SFINAE to enforce that X, Y are Foo-s

这是不可接受的,因为我确实需要知道这些嵌套类型 A...B...。我该怎么办?

您可以通过采用转发引用来接受参数,并分别传递它们的类型,包装在辅助类型中,tag

#include <type_traits>
#include <utility>

template <typename> struct tag {};

template <typename X, typename Y, typename... A, typename... B>
void foo(X&& x, Y&& y, tag<Foo<A...>>, tag<Foo<B...>>)
{
    // handle x and y
}

template <typename X, typename Y>
void foo(X&& x, Y&& y)
{
    return foo(std::forward<X>(x), std::forward<Y>(y)
             , tag<typename std::decay<X>::type>{}
             , tag<typename std::decay<Y>::type>{});
}

DEMO