代码之家  ›  专栏  ›  技术社区  ›  user11611653

为什么我的custon const_iterator end()函数在使用gtest时不编译?

  •  0
  • user11611653  · 技术社区  · 2 年前

    我正在努力学习c++标准库的工作原理及其数据结构,我正在实现一个数组和一些迭代器,只是为了学习。我正在使用Gtest/gmock对VisualStudio2022进行一些TDD,目前我有 array , const_iterator iterator 类及其相应的测试,一切正常。

    但是,当我在数组结构中添加迭代器函数(begin、end、cbegin、cend)的代码时,gtest无法编译,从而引发一个错误,该错误对应于 const_iterator end() const 作用

    Build started at 6:45 PM...
    1>------ Build started: Project: CppStd Test, Configuration: Debug x64 ------
    1>array_test.cpp
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25): error C2440: '<function-style-cast>': cannot convert from 'const int *' to 'cppstd::const_iterator<T>'
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25): error C2440:         with
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25): error C2440:         [
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25): error C2440:             T=int
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25): error C2440:         ]
    1>(compiling source file 'array_test.cpp')
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>'cppstd::const_iterator<T>::const_iterator': no overloaded function could convert all the argument types
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>  C:\Users\PC\Visual Studio\CppStd\CppSTD\const_iterator.h(130,1):
    1>  could be 'cppstd::const_iterator<T>::const_iterator(cppstd::const_iterator<T> &&)'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>      C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>      'cppstd::const_iterator<T>::const_iterator(cppstd::const_iterator<T> &&)': cannot convert argument 1 from 'const int *' to 'cppstd::const_iterator<T> &&'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>          C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,38):
    1>          Reason: cannot convert from 'const int *' to 'cppstd::const_iterator<T>'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>  C:\Users\PC\Visual Studio\CppStd\CppSTD\const_iterator.h(130,1):
    1>  or       'cppstd::const_iterator<T>::const_iterator(const cppstd::const_iterator<T> &)'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>      C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>      'cppstd::const_iterator<T>::const_iterator(const cppstd::const_iterator<T> &)': cannot convert argument 1 from 'const int *' to 'const cppstd::const_iterator<T> &'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>          C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,38):
    1>          Reason: cannot convert from 'const int *' to 'const cppstd::const_iterator<T>'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>  C:\Users\PC\Visual Studio\CppStd\CppSTD\const_iterator.h(31,3):
    1>  or       'cppstd::const_iterator<T>::const_iterator(int *) noexcept'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>      C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>      'cppstd::const_iterator<T>::const_iterator(int *) noexcept': cannot convert argument 1 from 'const int *' to 'int *'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>          C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,38):
    1>          Conversion loses qualifiers
    1>  C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>  while trying to match the argument list '(const int *)'
    1>C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(55,25):
    1>the template instantiation context (the oldest one first) is
    1>  C:\Users\PC\Visual Studio\CppStd\CppStd Test\array_test.cpp(64,30):
    1>  see reference to class template instantiation 'cppstd::array<int,3>' being compiled
    1>  C:\Users\PC\Visual Studio\CppStd\CppSTD\array.h(53,42):
    1>  while compiling class template member function 'cppstd::const_iterator<T> cppstd::array<T,3>::end(void) noexcept const'
    1>        with
    1>        [
    1>            T=int
    1>        ]
    1>      C:\Users\PC\Visual Studio\CppStd\packages\gmock.1.11.0\lib\native\include\gtest\gtest-printers.h(136,24):
    1>      see the first reference to 'cppstd::array<int,3>::end' in 'testing::internal::ContainerPrinter::PrintValue'
    1>const_iterator_test.cpp
    1>iterator_test.cpp
    1>Generating Code...
    1>Done building project "CppStd Test.vcxproj" -- FAILED.
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    ========== Build completed at 6:45 PM and took 11.959 seconds ==========
    

    我对失败编译的实现如下:

    template<typename T, std::size_t Size>
    struct array
    {
        using value_type = T;
        using size_type = std::size_t;
        using difference_type = std::ptrdiff_t;
        using reference = value_type&;
        using const_reference = const value_type&;
        using pointer = value_type*;
        using const_pointer = const value_type*;
        using iterator = cppstd::iterator<T>;
        using const_iterator = cppstd::const_iterator<T>;
        
        value_type m_array[Size];
    
        [[nodiscard]] constexpr iterator begin() noexcept
        {
            return iterator(&m_array[0]);
        }
    
        [[nodiscard]] constexpr iterator end() noexcept
        {
            return iterator(&m_array[0] + Size);
        }
    
        [[nodiscard]] constexpr const_iterator begin() const noexcept
        {
            return const_iterator(&m_array[0]);
        }
    
        [[nodiscard]] constexpr const_iterator end() const noexcept
        {
            // HERE IS WHERE I GET THE ERROR
            return const_iterator(&m_array[0] + Size);
        }
    };
    
    
    template<typename T>
    class const_iterator
    {
    public:
        using iterator_category = std::random_access_iterator_tag;
        using value_type = T;
        using size_type = std::size_t;
        using difference_type = std::ptrdiff_t;
        using reference = value_type&;
        using pointer = value_type*;
        using const_reference = const value_type&;
        using const_pointer = const value_type*;
    
        T* m_pointer;
    
        const_iterator() = default;
    
        explicit const_iterator(pointer ptr) noexcept : m_pointer{ ptr } {}
    };
    

    如果我为其他任何事情更改函数的名称,错误就会停止,即使我没有任何测试或类型引用迭代器或数组类,它也会继续出现。

    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    
    #include "../CppSTD/const_iterator.h"
    
    using namespace ::testing;
    
    class const_iterator_test : public Test
    {
    public:
        void SetUp() override
        {
            ptr_int = new int[5];
            for (int i{ 0 }; i < 5; ++i)
                ptr_int[i] = i + 1;
        }
    
        void TearDown() override
        {
            delete ptr_int;
            ptr_int = nullptr;
        }
    
        int* ptr_int{ nullptr };
    
    private:
    
    };
    

    我看不出什么是显而易见的。这很奇怪,因为如果我在没有gtest的情况下编译,一切都会正常运行。 我在这里留下我的数组和迭代器类的完整定义: FULL CODE

    提前谢谢。

    1 回复  |  直到 2 年前
        1
  •  0
  •   3CxEZiVlQ    2 年前
    'cppstd::const_iterator<T>::const_iterator(int *) noexcept': cannot convert argument 1 from 'const int *' to 'int *'
    

    class const_iterator ,构造函数

    explicit const_iterator(pointer ptr) noexcept : m_pointer{ ptr } {}
    

    应该是

    explicit const_iterator(const_pointer ptr) noexcept : m_pointer{ ptr } {}
    

    T* m_pointer;
    

    应该是

    const_pointer m_pointer;
    // const T* m_pointer;