I have a code that compiled just fine in Visual Studio 2017 until today, but now I keep getting template instantiation errors from std::vector which are provided at the end of the post. I should add that not a single line of code has been changed between then(when code compiled ok) and now.
When I isolated the problem, it strangely boiled down to whether or not std::vector is included in one of the header files. The following code reproduces the errors:
(Note that the code does not make much sense as it is.)
CDataUnit_ALB.h:
#pragma once
#include "DataUnit\CDataUnit.h"
// #include <vector> // <== UnREM'ing this results in compile errors
class CDataUnit_ALB :
public CDataUnit
{
public:
friend
void swap(CDataUnit_ALB& lhs, CDataUnit_ALB& rhs) {
using Base_t = CDataUnit;
using std::swap;
swap(static_cast<Base_t&>(lhs), static_cast<Base_t&>(rhs));
}
};
CDataUnit.h
#pragma once
#include <memory>
template<typename Tp_Alloc = std::allocator<char>>
class basic_CDataUnit
{
public:
using allocator_type =
typename std::allocator_traits<Tp_Alloc>::template rebind_alloc<char>;
struct Representation :
public allocator_type
{
char* data;
friend
void swap(Representation& lhs, Representation& rhs) noexcept {
using std::swap;
swap<allocator_type>(lhs, rhs); // swap base members
swap(lhs.data, rhs.data);
}
};
Representation m_r;
friend
void swap(basic_CDataUnit& lhs, basic_CDataUnit& rhs) noexcept {
using std::swap;
swap(lhs.m_r, rhs.m_r);
}
};
using CDataUnit = basic_CDataUnit<>;
main.cpp
#include "DataUnit\CDataUnit_ALB.h"
int main() {
return 0;
}
Here is the compile errors I am getting:
1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>CDataUnit_ALB.cpp
1>c:\[path_to_msvc]\14.11.25503\include\vector(2131): error C2039: '_Alloc': is not a member of 'std::allocator<char>'
1>c:\[path_to_msvc]\14.11.25503\include\iosfwd(628): note: see declaration of 'std::allocator<char>'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2179): note: see reference to class template instantiation 'std::_Vb_iter_base<_Alvbase_wrapped>' being compiled
1> with
1> [
1> _Alvbase_wrapped=std::allocator<char>
1> ]
1>c:\[path_to_project]\cdataunit.h(20): note: see reference to class template instantiation 'std::_Vb_reference<std::allocator<char>>' being compiled
1>c:\[path_to_project]\cdataunit.h(18): note: while compiling class template member function 'void swap(basic_CDataUnit<std::allocator<char>>::Representation &,basic_CDataUnit<std::allocator<char>>::Representation &) noexcept'
1>c:\[path_to_project]\cdataunit.h(25): note: see reference to class template instantiation 'basic_CDataUnit<std::allocator<char>>::Representation' being compiled
1>c:\[path_to_project]\cdataunit_alb.h(10): note: see reference to class template instantiation 'basic_CDataUnit<std::allocator<char>>' being compiled
1>c:\[path_to_msvc]\14.11.25503\include\vector(2131): error C2061: syntax error: identifier '_Alloc'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2131): error C2238: unexpected token(s) preceding ';'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2065: '_Alvbase': undeclared identifier
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2923: 'std::allocator_traits': '_Alvbase' is not a valid template type argument for parameter '_Alloc'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2955: 'std::allocator_traits': use of class template requires template argument list
1>c:\[path_to_msvc]\14.11.25503\include\xmemory0(878): note: see declaration of 'std::allocator_traits'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2039: 'size_type': is not a member of 'std::allocator_traits<_Alloc>'
1>c:\[path_to_msvc]\14.11.25503\include\xmemory0(196): note: see declaration of 'std::allocator_traits<_Alloc>'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2061: syntax error: identifier 'size_type'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2132): error C2238: unexpected token(s) preceding ';'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2065: '_Alvbase': undeclared identifier
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2923: 'std::allocator_traits': '_Alvbase' is not a valid template type argument for parameter '_Alloc'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2955: 'std::allocator_traits': use of class template requires template argument list
1>c:\[path_to_msvc]\14.11.25503\include\xmemory0(878): note: see declaration of 'std::allocator_traits'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2039: 'difference_type': is not a member of 'std::allocator_traits<_Alloc>'
1>c:\[path_to_msvc]\14.11.25503\include\xmemory0(196): note: see declaration of 'std::allocator_traits<_Alloc>'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2061: syntax error: identifier 'difference_type'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2133): error C2238: unexpected token(s) preceding ';'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2134): error C2065: '_Alvbase': undeclared identifier
1>c:\[path_to_msvc]\14.11.25503\include\vector(2134): error C2923: 'std::_Rebind_alloc_t': '_Alvbase' is not a valid template type argument for parameter '_Alloc'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2141): error C2061: syntax error: identifier '_Sizet'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2148): error C2061: syntax error: identifier '_Sizet'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2155): error C2061: syntax error: identifier '_Sizet'
1>c:\[path_to_msvc]\14.11.25503\include\vector(2172): error C3646: '_Myoff': unknown override specifier
1>c:\[path_to_msvc]\14.11.25503\include\vector(2172): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Strange Observations:
1- The first error(i.e. error C2039: '_Alloc': is not a member of 'std::allocator<char>') originates from the typedef using _Alvbase = typename _Alvbase_wrapped::_Alloc; in class _Vb_iter_base which, it seems, has to do with bool specialization of std::vector and that specialization is not used anywhere in the code.
2- Replacing swap<allocator_type>(lhs, rhs); in friend void swap(Representation& lhs, Representation& rhs) in CDataUnit.h with swap(static_cast<allocator_type&>(lhs), static_cast<allocator_type&>(rhs)); seems to fix the problem.
I appreciate any ideas on why this is happening.