美文网首页
C++ 20:Concepts

C++ 20:Concepts

作者: fck_13 | 来源:发表于2020-05-13 15:55 被阅读0次

    我们从一个例子来引入concepts:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    int main()
    {
        std::vector<int> container{1, 5, 4, 3, 2};
    
        std::ostream_iterator<int> out(std::cout, " ");
        std::copy(std::begin(container), std::end(container), out);
        std::cout<<"\n";
    
        std::sort(std::begin(container), std::end(container));
        
        std::copy(std::begin(container), std::end(container), out);
        std::cout<<"\n";
    
        return 0;
    }
    

    运行结果如下:


    image.png

    程序正确,得到了我们想要的结果。

    现在我们修改一下容器的类型,改为std::list。然后编译就出错了,而且错误信息很多,根本就没有办法知道错误到底是啥,需要在哪里修改。

    image.png

    然后你会一点一点的分析,最后找到了答案了:
    迭代器分为五个类别(在C++20之前是5个,C++20增加了contiguous_iterator_tag ):

    struct input_iterator_tag {};
    struct output_iterator_tag {};
    struct forward_iterator_tag : input_iterator_tag {};
    struct bidirectional_iterator_tag : forward_iterator_tag {};
    struct random_access_iterator_tag : bidirectional_iterator_tag {};
    

    std::sort中的迭代器参数需要的是random_access_iterator_tagstd::vector的迭代器类型为random_access_iterator_tag,而std::list的迭代器类型为bidirectional_iterator_tag,所以编译错误。
    当我们找到问题的答案后,才发现这个问题的原因是如此的简单,但是编译器给出的错误信息确是如此的复杂且不知所以然。

    这里的问题在于,对于std::sort的参数是有限制的,不是说任何的迭代器都是可用的。为了明确编程中的一些限制,C++给出了concepts。

    我们继续我们上面的例子,修改如下:

    #include <concepts>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    #include <list>
    
    template<typename T>
    concept sortable = requires(T t, size_t i){t[i];};
    
    template<sortable T>
    void sort(T& t){
        std::sort(std::begin(t), std::end(t));
    }
    
    int main()
    {
        std::vector<int> container{1, 5, 4, 3, 2};
    
        std::ostream_iterator<int> out(std::cout, " ");
        std::copy(std::begin(container), std::end(container), out);
        std::cout<<"\n";
    
        sort(container);
    
        std::copy(std::begin(container), std::end(container), out);
        std::cout<<"\n";
    
        return 0;
    }
    

    这里我们增加了

    template<typename T>
    concept sortable = requires(T t, size_t i){t[i];};
    

    意思是新增加了一种concept,也就是一种限制,将一个类型现定于有operator[]成员函数。这里我们假设有这个成员函数的类型满足random_access_iterator_tag迭代器。
    然后我们声明了一个sort函数:

    template<sortable T>
    void sort(T& t){
        std::sort(std::begin(t), std::end(t));
    }
    

    告知调用者其参数类型应当满足sortable这个限制。

    然后我们将std::vector<int> container{1, 5, 4, 3, 2};改为std::list<int> container{1, 5, 4, 3, 2};,重新编译代码,得到下面的错误

    image.png
    这样看起来是不是容易理解多了。

    相关文章

      网友评论

          本文标题:C++ 20:Concepts

          本文链接:https://www.haomeiwen.com/subject/slvnnhtx.html