I'm trying to write my vector, to realize the function of the one in STL as much as possible.
However when I tried to run a test project, Visual Studio told me that, const version of begin(), const version of end(), cbegin() and cend() trigger C2373 errors due to redefinitions.
I'm sure I didn't define these methods twice. Here is a minimal version to reproduce these errors.
#include <algorithm> //for std::reverse_iterator
template <typename Type>
class vector_iterator;
template <typename Type>
class vector
{
friend class vector_iterator<Type>;
public:
// These alies are used as return type.
using iterator = vector_iterator<Type>;
using const_iterator = const vector_iterator<Type>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
constexpr vector() noexcept{}; // simplified constructor
constexpr vector_iterator<Type> begin() noexcept;
constexpr const vector_iterator<Type> begin() const noexcept; // causes C2373.
constexpr const vector_iterator<Type> cbegin() const noexcept; // causes C2373.
constexpr vector_iterator<Type> end() noexcept;
constexpr const vector_iterator<Type> end() const noexcept; // causes C2373.
constexpr const vector_iterator<Type> cend() const noexcept; // causes C2373.
private:
size_t size_ = 0;
Type* ptr_data_ = nullptr;
};
// non-const begin(), normal
template <typename Type>
constexpr typename vector<Type>::iterator vector<Type>::begin() noexcept
{
return vector_iterator<Type>(ptr_data_);
}
// const begin(), causes "C2373: redefinition; different type modifiers"
template <typename Type>
constexpr typename vector<Type>::const_iterator vector<Type>::begin() const noexcept
{
return const_iterator(ptr_data_);
}
// cbegin(), causes "C2373: redefinition; different type modifiers"
template <typename Type>
constexpr typename vector<Type>::const_iterator vector<Type>::cbegin() const noexcept
{
return const_iterator(ptr_data_);
}
// non-const end(), normal
template <typename Type>
constexpr typename vector<Type>::iterator vector<Type>::end() noexcept
{
return iterator(ptr_data_ + size_);
}
// const end(), causes "C2373: redefinition; different type modifiers"
template <typename Type>
constexpr typename vector<Type>::const_iterator vector<Type>::end() const noexcept
{
return const_iterator(ptr_data_ + size_);
}
// cend(), causes "C2373: redefinition; different type modifiers"
template <typename Type>
constexpr typename vector<Type>::const_iterator vector<Type>::cend() const noexcept
{
return const_iterator(ptr_data_ + size_);
}
// simplified vector_iterator
template <typename Type>
class vector_iterator
{
public:
explicit vector_iterator(Type* ptr) : iterator_ptr_(ptr) {}; // iterator constructor
private:
Type* iterator_ptr_ = nullptr;
};
int main(void)
{
vector<int> tmp; // tries to construct a vector
return 0;
}
Visual Studio produce an error list as follows:
| Code | Description | Line (marked in the comments) |
|---|---|---|
C2373 |
'clb_container::vector<Type,Allocator>::begin': redefinition; different type modifiers | 43 |
C2373 |
'clb_container::vector<Type,Allocator>::cbegin': redefinition; different type modifiers | 50 |
C2373 |
'clb_container::vector<Type,Allocator>::end': redefinition; different type modifiers | 64 |
C2373 |
'clb_container::vector<Type,Allocator>::cend': redefinition; different type modifiers | 71 |
The debug log is as follows:
Build started at 21:51...
1>------ Build started: Project: Development Test, Configuration: Debug x64 ------
1>Development Test.cpp
1>Development Test.cpp(43,63): error C2373: 'vector<Type>::begin': redefinition; different type modifiers
1>Development Test.cpp(21,43):
1>see declaration of 'vector<Type>::begin'
1>Development Test.cpp(50,63): error C2373: 'vector<Type>::cbegin': redefinition; different type modifiers
1>Development Test.cpp(22,43):
1>see declaration of 'vector<Type>::cbegin'
1>Development Test.cpp(64,63): error C2373: 'vector<Type>::end': redefinition; different type modifiers
1>Development Test.cpp(25,43):
1>see declaration of 'vector<Type>::end'
1>Development Test.cpp(71,63): error C2373: 'vector<Type>::cend': redefinition; different type modifiers
1>Development Test.cpp(26,43):
1>see declaration of 'vector<Type>::cend'
1>Done building project "Development Test.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 21:51 and took 00.648 seconds ==========
I have tried the following steps:
- I commented all the methods mentioned above and recompiled it. Errors disappeared at once.
- Then I uncommented them one by one and found that whenever one of
constversion ofbegin(),constversion ofend,cbegin()andcend()is available,C2373would occurred again. - I passed each of these code snippets to Copilot and Claude-3-Sonnet, respectively, and they found no obvious redefinitions.
- At last, I installed "C++ Clang tools for Windows under Desktop development with C++" with Visual Studio Installer, and configured the test project to use Clang.
C2373disappeared, and the program compiled normally. However, if I changed the "Platform Toolset" back to the default "Visual Studio 2022(v143)", errors occur again. So I think this problem is probably caused by Visual C++ 2022.
However, as a part of my tiny STL, I hope it can compile normally under most compilers, rather than failing for some inexplicable reason, especially on a platform with many users like Visual Studio, but I still can't find the real problem.
constexprimpliesconst...are the same thing, except for return type. And you can't do overloads that only differ in return type.
Still; I'm confused as to why it compiles with some compilers... so I might actually be horribly wrong...
Ok, cppreference says:
Are we looking at different language standards on the compilers that you tried?