可变模板模板参数语法

variadic template template parameter syntax

本文关键字:语法 参数      更新时间:2023-10-16

我有这个模板函数(我记得在SO的某个地方看到类似的东西)。它适用于std::functionstd::list(作为Container)。但是我不能真正理解template <typename, typename...> class Container的语法。<中的>似乎是一种不同的语言(与C/旧c++相比)。有人能解释一下或者给出一个好的参考来解释这个吗?

template <typename T, template <typename, typename...> class Container>
static bool contained(const T & x, const Container<T> & xs) {
    return std::find(xs.begin(),xs.end(),x) != xs.end();
}
template <typename T, template <typename, typename...> class Container>

上面表明Container是一个模板模板形参,这意味着传递给函数模板的Container类型本身必须是一个至少接受一个模板实参的模板——第二个模板实参之后将被参数包(typename...)使用。

但是你的函数模板有一个问题。正如我所解释的,您指出Container必须是接受一个或多个模板实参的类模板,但是相应的函数形参(xs)表明它接受单个模板实参。之所以对std::liststd::vectorstd::deque有效,是因为它们各自的第二个模板参数,分配器类型,有一个默认值(std::allocator<T>)。如果这些容器具有非默认的分配器类型,那么函数模板将无法与它们一起工作。

为了解决这个问题,xs的类型也需要容纳额外的模板参数。

template <typename T, typename... Params, 
          template <typename, typename...> class Container>
static bool contained(const T & x, const Container<T, Params...> & xs) {
    return std::find(xs.begin(),xs.end(),x) != xs.end();
}

然而,这个特殊的问题可以在不使用模板模板参数的情况下解决。只要接受任何类型的Container,而不是将其作为模板进行规定。您正在搜索的元素的类型可以通过使用Container::value_type嵌套类型来指定,该类型是标准库中所有容器定义的。
template <typename Container>
static bool contained(typename Container::value_type const& x, 
                      const Container& xs) {
    return std::find(xs.begin(),xs.end(),x) != xs.end();
}

此外,c++ 11添加了std::any_of,它的功能与contained()相同。