我正在尝试试用this page.中提供的C ++中的openssl示例。项目示例文件名为env-encrypt.cxx,可以在该页面的tar.gz中下载。
当我尝试在Visual Studio 2017上运行该示例时,出现以下错误:'Initializing': cannot convert from 'zallocator<char>' to 'zallocator<U>' in file xstring line 1998
。
这是我得到的输出:
1>------ Build started: Project: ConsoleApplication3, Configuration: Debug Win32 ------
1>ConsoleApplication3.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xstring(1998): error C2440: 'initializing': cannot convert from 'zallocator<char>' to 'zallocator<U>'
1> with
1> [
1> U=std::_Container_proxy
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xstring(1998): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xstring(1997): note: while compiling class template member function 'void std::_String_alloc<std::_String_base_types<_Elem,_Alloc>>::_Free_proxy(void)'
1> with
1> [
1> _Elem=char,
1> _Alloc=zallocator<char>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xstring(1949): note: see reference to function template instantiation 'void std::_String_alloc<std::_String_base_types<_Elem,_Alloc>>::_Free_proxy(void)' being compiled
1> with
1> [
1> _Elem=char,
1> _Alloc=zallocator<char>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xstring(2066): note: see reference to class template instantiation 'std::_String_alloc<std::_String_base_types<_Elem,_Alloc>>' being compiled
1> with
1> [
1> _Elem=char,
1> _Alloc=zallocator<char>
1> ]
1>c:\users\xxx\source\repos\consoleapplication3\consoleapplication3\consoleapplication3.cpp(86): note: see reference to class template instantiation 'std::basic_string<char,std::char_traits<char>,zallocator<char>>' being compiled
1>Done building project "ConsoleApplication3.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
为了简化操作,这是我下载的env-encrypt.cxx文件中的zallocator类:
template <typename T>
struct zallocator
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
pointer address(reference v) const { return &v; }
const_pointer address(const_reference v) const { return &v; }
pointer allocate(size_type n, const void* hint = 0) {
if (n > std::numeric_limits<size_type>::max() / sizeof(T))
throw std::bad_alloc();
return static_cast<pointer> (::operator new (n * sizeof(value_type)));
}
void deallocate(pointer p, size_type n) {
OPENSSL_cleanse(p, n * sizeof(T));
::operator delete(p);
}
size_type max_size() const {
return std::numeric_limits<size_type>::max() / sizeof(T);
}
template<typename U>
struct rebind
{
typedef zallocator<U> other;
};
void construct(pointer ptr, const T& val) {
new (static_cast<T*>(ptr)) T(val);
}
void destroy(pointer ptr) {
static_cast<T*>(ptr)->~T();
}
#if __cpluplus >= 201103L
template<typename U, typename... Args>
void construct(U* ptr, Args&& ... args) {
::new (static_cast<void*> (ptr)) U(std::forward<Args>(args)...);
}
template<typename U>
void destroy(U* ptr) {
ptr->~U();
}
#endif
};
这是secure_string的typedef,它正在调用zallocator,这似乎是问题所在:
typedef std::basic_string<char, std::char_traits<char>, zallocator<char> > secure_string;
如果您想查看完整的源代码,可以从我链接的页面下载它。
编辑:当我添加此行时:
template<class U> zallocator(const zallocator<U>&) noexcept { }
按照此reddit帖子中建议的类定义,我遇到另一个异常:'zallocator :: zallocator':没有合适的默认构造函数。
我尝试添加没有这样的参数的构造函数:`
template<class U> zallocator() noexcept { }
`,但仍然出现相同的错误
答案 0 :(得分:1)
看看cppreference的allocator documentation和allocator completeness requirements。最后一个链接具有最小c ++ 17分配器的以下示例:
template <class T>
struct Mallocator {
typedef T value_type;
Mallocator() = default;
template <class U> constexpr Mallocator(const Mallocator<U>&) noexcept {}
[[nodiscard]] T* allocate(std::size_t n) {
if(n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
if(auto p = static_cast<T*>(std::malloc(n*sizeof(T)))) return p;
throw std::bad_alloc();
}
void deallocate(T* p, std::size_t) noexcept { std::free(p); }
};
template <class T, class U>
bool operator==(const Mallocator<T>&, const Mallocator<U>&) { return true; }
template <class T, class U>
bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { return false; }
这应该使您了解如何修复代码。
您缺少比较运算符:operator==
and operator!=
:
template <typename U>
friend bool operator==(const zallocator<T> & a, const zallocator<U> & b)
{
return true;
}
template <typename U>
friend bool operator!=(const zallocator<T> & a, const zallocator<U> & b)
{
return false;
}
以及一些构造函数:
constexpr zallocator() noexcept = default;
template< class U>
constexpr zallocator(const zallocator<U>& other) noexcept
{
}
template<class U> zallocator() noexcept { }
但这不是默认的构造函数。默认的构造函数不应模板化。