I'm trying to learn how the c++ standard library works and it's data structures and I'm implementing an array and some iterators just for learning purposes. I'm using Gtest/gmock to do some TDD with VisualStudio 2022 and I'm currently have the array
, const_iterator
and iterator
classes with their corresponding tests and everything is working fine.
But when I add the code for the iterator functions (begin, end, cbegin, cend) in the array struct, gtest fails to compile throwing me an error that corresponds to the const_iterator end() const
function.
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 ==========
My implementation of the failure compile is the following:
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 } {}
};
The error stops if I change the name of the function for anything else and it keeps appearing even if I don't have any test or types referring to my iterator or array class.
#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:
};
Perhaps is something very obvious that I don't see. And is very weird because if I compile without gtest everything runs normally. I leave here the full definition of my array and iterator classes: FULL CODE
Thank you in advance.
'cppstd::const_iterator<T>::const_iterator(int *) noexcept': cannot convert argument 1 from 'const int *' to 'int *'
In the class const_iterator
, the constructor
explicit const_iterator(pointer ptr) noexcept : m_pointer{ ptr } {}
should be
explicit const_iterator(const_pointer ptr) noexcept : m_pointer{ ptr } {}
And
T* m_pointer;
should be
const_pointer m_pointer;
// const T* m_pointer;