c++ - 如何指示容器模板参数的类型?

标签 c++ templates c++11

假设我们有这个模板

template<typename Container, typename T> 
bool    contains (const Container & theContainer, const T & theReference) {
     ...
}

怎么能说,容器中的元素显然应该是T类型?

这一切都可以缩写吗(可能在 C++11 中)?

最佳答案

虽然使用 value_type 的其他答案是正确的,但此常见问题的规范解决方案是首先不传递容器:使用标准库语义,并且传递一对迭代器

通过传递迭代器,您不必担心容器本身。您的代码也更加通用:您可以对范围进行操作,您可以使用反向迭代器,您可以将您的模板与其他标准算法等相结合。:

template<typename Iterator, typename T> 
bool contains (Iterator begin, Iterator end, const T& value) {
     ...
}

int main(){
    std::vector<int> v { 41, 42 };
    contains(std::begin(v), std::end(v), 42);
};

如果要检查Iterator携带的类型,可以使用std::iterator_traits :

static_assert(std::is_same<typename std::iterator_traits<Iterator>::value_type, T>::value, "Wrong Type");

(注意这个断言一般是不需要的:如果你提供了一个与T不可比较的值,模板一开始就不会编译)


最终的模板如下所示:

template<typename Iterator, typename T> 
bool contains (Iterator begin, Iterator end, const T& value) {

    static_assert(std::is_same<typename std::iterator_traits<Iterator>::value_type, T>::value, "Wrong Type");

     while(begin != end)
       if(*begin++ == value)
         return true;
     return false;
}

Live demo


注意事项:

1) 这应该不足为奇,但我们的 contains 模板现在与 std::find 具有几乎相同的签名。 (返回一个迭代器):

template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );

2)如果修改原contains的签名太多,可以随时将调用转发到我们的新模板:

template<typename Container, typename T> 
bool contains (const Container & theContainer, const T & theReference) {
     return contains(std::begin(theContainer), std::end(theContainer), theReference);
}

关于c++ - 如何指示容器模板参数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27077643/

相关文章:

c++ - 使用 C++ 将曲线重新采样为偶数长度的段

javascript - 当(仅)使用模板系统时,我应该如何管理子模板的 CSS、javascript 等?

c++ - 具有不变返回类型的模板类中的交换运算符

c++ - boost::split 在字符串的开头和结尾留下空标记——这是期望的行为吗?

在参数中强制执行单一类型的 C++ 参数包

c++ - 实现多线程 UDP 服务器(线程池?)的问题

c++ - 使用 std::transform,最好使用 begin() 或 back_inserter()?

php - 我的部分模板或 html 消失了。为 Prestashop 1.7.6.1、php 7.1.9 创建模块

c++ - 使用 decltype(this) 获取函数引用

c++ - MFC/C++ 组合框 : disable drawing of Dropdown closing & opening (UI freeze)