直到今天,我有一个代码在 Visual Studio 2017 中编译得很好,但现在我不断收到来自 std::vector
的模板实例化错误。在帖子末尾提供。我应该补充一点,从那时(当代码编译正常时)到现在,没有一行代码被更改。
当我隔离问题时,它奇怪地归结为是否 std::vector
包含在其中一个头文件中。以下代码重现错误:
(请注意,代码并没有多大意义。)
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<>;
主要.cpp
#include "DataUnit\CDataUnit_ALB.h"
int main() {
return 0;
}
这是我遇到的编译错误:
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
奇怪的观察:
1- 第一个错误(即 error C2039: '_Alloc': is not a member of 'std::allocator<char>'
)源自 typedef using _Alvbase = typename _Alvbase_wrapped::_Alloc;
在类里面_Vb_iter_base
这似乎与 bool
有关特化std::vector
并且代码中的任何地方都没有使用这种特化。
2- 替换 swap<allocator_type>(lhs, rhs);
在friend void swap(Representation& lhs, Representation& rhs)
在 CDataUnit.h 中使用 swap(static_cast<allocator_type&>(lhs), static_cast<allocator_type&>(rhs));
似乎解决了这个问题。
我很感激任何关于为什么会发生这种情况的想法。
最佳答案
考虑一下:
template<class T> struct foo : T { };
template<class T> void swap(foo<T>, foo<T>);
template<class T> void swap(T&, T&);
int i = 1, j = 2;
swap<int>(i, j);
你认为会发生什么?
main.cpp:1:36: error: base specifier must name a class
template<class T> struct foo : T { };
^
main.cpp:6:15: note: in instantiation of template class 'foo<int>' requested here
swap<int>(i, j);
^
因为您指定了一个显式模板参数,所以它被替换到重载集中每个函数模板的签名中,这意味着如果类模板,您可以使用它们永远不会使用的类型来实例化类模板用于其中一个重载的签名。
在上面的示例中,该替换触发了 foo<int>
的实例化,这会触发一个硬错误。在您的代码中,它是 std::_Vb_reference<std::allocator<char>>
.
只是...不要这样做。
关于c++ - 在头文件中包含 std::vector 会导致模板实例化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47307748/