'正在初始化':无法从'zallocator <char>'转换为'zallocator <u>'

时间:2018-11-07 19:06:11

标签: c++

我正在尝试试用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 { }

`,但仍然出现相同的错误

1 个答案:

答案 0 :(得分:1)

看看cppreference的allocator documentationallocator 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 { }

但这不是默认的构造函数。默认的构造函数不应模板化。