模板化 ctor 上的编译器错误(这是编译器错误吗?)
Compiler error on templated ctor (is this a compiler bug?)
当我尝试在 Visual Studio 2019 年编译来自 this post 的代码(见下文)时,我在模板化复制构造函数的行收到以下编译器错误:
Error C2439 'PreAllocator<_Newfirst>::memory_ptr': member could not be initialized
Error C2440 'initializing': cannot convert from 'T *const ' to 'T *'
Error C2248 'PreAllocator<int>::memory_size': cannot access private member declared in class 'PreAllocator<int>'
Error C2248 'PreAllocator<int>::memory_ptr': cannot access private member declared in class 'PreAllocator<int>'
这是编译器错误还是我遗漏了什么?
template <typename T>
class PreAllocator
{
private:
T* memory_ptr;
std::size_t memory_size;
public:
typedef std::size_t size_type;
typedef T* pointer;
typedef T value_type;
PreAllocator(T* memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
PreAllocator(const PreAllocator& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator& operator = (const PreAllocator<U>& other) { return *this; }
PreAllocator<T>& operator = (const PreAllocator& other) { return *this; }
~PreAllocator() {}
pointer allocate(size_type n, const void* hint = 0) { return memory_ptr; }
void deallocate(T* ptr, size_type n) {}
size_type max_size() const { return memory_size; }
};
int main()
{
int my_arr[100] = { 0 };
std::vector<int, PreAllocator<int>> my_vec(0, PreAllocator<int>(&my_arr[0], 100));
}
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
此构造函数尝试从 U*
类型的 other.memory_ptr
初始化 T*
类型的 memory_ptr
,这与 T*
不同(因为否则一个副本构造函数将被调用)。 std::vector
实现显然使用内部类型来实例化分配器以分配存储,并且指向该类型的指针不能隐式转换为您期望的 int*
。
您必须显式转换指针,或在内部存储 void*
,然后您将在 allocate
成员函数中将其转换为 T*
。
template <typename T>
class PreAllocator
{
private:
void* memory_ptr;
...
public:
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() :
memory_ptr(other.memory_ptr), memory_size(other.memory_size) {}
pointer allocate(size_type n, const void* hint = 0)
{
return static_cast< pointer >(memory_ptr);
}
...
};
此外,在同一个构造函数中,您正在访问 PreAllocator<U>
的 memory_ptr
和 memory_size
成员,这是与 PreAllocator<T>
不同且不相关的类型(同样,因为 T
和 U
是不同的类型)。这些成员是私有的,因为 class,这给了你访问错误。
您可以通过使这些成员成为 public 或为他们添加 public 访问器来缓解这种情况,或者通过如下声明使 PreAllocator
朋友的所有专业化:
template <typename T>
class PreAllocator
{
template< typename U >
friend class PreAllocator;
...
};
当我尝试在 Visual Studio 2019 年编译来自 this post 的代码(见下文)时,我在模板化复制构造函数的行收到以下编译器错误:
Error C2439 'PreAllocator<_Newfirst>::memory_ptr': member could not be initialized
Error C2440 'initializing': cannot convert from 'T *const ' to 'T *'
Error C2248 'PreAllocator<int>::memory_size': cannot access private member declared in class 'PreAllocator<int>'
Error C2248 'PreAllocator<int>::memory_ptr': cannot access private member declared in class 'PreAllocator<int>'
这是编译器错误还是我遗漏了什么?
template <typename T>
class PreAllocator
{
private:
T* memory_ptr;
std::size_t memory_size;
public:
typedef std::size_t size_type;
typedef T* pointer;
typedef T value_type;
PreAllocator(T* memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
PreAllocator(const PreAllocator& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator& operator = (const PreAllocator<U>& other) { return *this; }
PreAllocator<T>& operator = (const PreAllocator& other) { return *this; }
~PreAllocator() {}
pointer allocate(size_type n, const void* hint = 0) { return memory_ptr; }
void deallocate(T* ptr, size_type n) {}
size_type max_size() const { return memory_size; }
};
int main()
{
int my_arr[100] = { 0 };
std::vector<int, PreAllocator<int>> my_vec(0, PreAllocator<int>(&my_arr[0], 100));
}
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
此构造函数尝试从 U*
类型的 other.memory_ptr
初始化 T*
类型的 memory_ptr
,这与 T*
不同(因为否则一个副本构造函数将被调用)。 std::vector
实现显然使用内部类型来实例化分配器以分配存储,并且指向该类型的指针不能隐式转换为您期望的 int*
。
您必须显式转换指针,或在内部存储 void*
,然后您将在 allocate
成员函数中将其转换为 T*
。
template <typename T>
class PreAllocator
{
private:
void* memory_ptr;
...
public:
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() :
memory_ptr(other.memory_ptr), memory_size(other.memory_size) {}
pointer allocate(size_type n, const void* hint = 0)
{
return static_cast< pointer >(memory_ptr);
}
...
};
此外,在同一个构造函数中,您正在访问 PreAllocator<U>
的 memory_ptr
和 memory_size
成员,这是与 PreAllocator<T>
不同且不相关的类型(同样,因为 T
和 U
是不同的类型)。这些成员是私有的,因为 class,这给了你访问错误。
您可以通过使这些成员成为 public 或为他们添加 public 访问器来缓解这种情况,或者通过如下声明使 PreAllocator
朋友的所有专业化:
template <typename T>
class PreAllocator
{
template< typename U >
friend class PreAllocator;
...
};