簡體   English   中英

GCC 10.2 中是否缺少 std::basic_istringstream 的構造函數,如果是,我如何使用自定義分配器構造一個構造函數?

[英]Is there a missing constructor for std::basic_istringstream in GCC 10.2, and if so, how do I construct one with a custom allocator?

我有以下代碼:

#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <sstream>

class CustomAllocator
{
public:
    CustomAllocator(const std::size_t sizeBytes,
                    void* const start)
    :
        m_sizeBytes(sizeBytes),
        m_usedBytes(0),
        m_start(start),
        m_current(start)
    {

    }

    void* Allocate(const std::size_t& numBytes,
                   const std::uintptr_t& alignment)
    {
        std::size_t space = m_sizeBytes - m_usedBytes;
        if(std::align(alignment, numBytes, m_current, space))
        {
            // the amount used for alignment
            m_usedBytes += (m_sizeBytes-m_usedBytes) - space;
            // the amount actually needed
            m_usedBytes += numBytes;

            void* address = m_current;

            m_current = reinterpret_cast<void*>(
                reinterpret_cast<std::uintptr_t>(m_current) + numBytes);

            return address;
        }
        throw std::bad_alloc();
    }

    void Free(void* const ptr)
    {
        // do nothing in this Allocator, but other derived types may
    }

    void Clear()
    {
        m_current = m_start;
        m_usedBytes = 0;
    }

    std::size_t GetSize() const { return m_sizeBytes; }

    void* const GetStart() const { return m_start; }

protected:
    const std::size_t m_sizeBytes;
    std::size_t m_usedBytes;
    void* const m_start;
    void* m_current;
};
// many types derive from base CustomAllocator type

// allows for my custom allocators to be used in STL containers
template<typename T, typename Alloc>
class STLAdaptor
{
public:

    typedef T value_type;

    template<typename U>
    struct rebind
    {
        typedef STLAdaptor<U, Alloc> other;
    };

    STLAdaptor(Alloc& allocator)
    :
        m_allocator(allocator)
    {

    }

    template<typename U>
    STLAdaptor(const STLAdaptor<U, Alloc>& other) noexcept
    :
        m_allocator(other.m_allocator)
    {}

    [[nodiscard]] constexpr T* allocate(std::size_t n)
    {
        return reinterpret_cast<T*>
            (m_allocator.Allocate(n * sizeof(T), alignof(T)));
    }

    constexpr void deallocate(T* p, std::size_t n)
    {
        m_allocator.Free(p);
    }

    std::size_t MaxAllocationSize() const
    {
        return m_allocator.GetSize();
    }

    bool operator==(const STLAdaptor<T,Alloc>& rhs)
    {
        return m_allocator.GetStart() == rhs.m_allocator.GetStart();
    }

    bool operator!=(const STLAdaptor<T,Alloc>& rhs)
    {
        return !(*this == rhs);
    }

    Alloc& m_allocator;
};

int main()
{
    const std::size_t memSize = 10000000;
    void* mem = std::malloc(memSize);

    CustomAllocator customAlloc(memSize, mem);

    std::basic_string<char, std::char_traits<char>,
        STLAdaptor<char, CustomAllocator>>
        myString(customAlloc);

    myString = "something something";

    std::basic_istringstream<char, std::char_traits<char>,
        STLAdaptor<char, CustomAllocator>>
        iss(myString, std::ios_base::in, customAlloc);

    std::free(mem);

    return 0;
}

使用 GCC 10.2 -Wall -fexceptions -std=c++2a -g編譯我得到以下錯誤:

||=== Build: Debug in CPPTESTS (compiler: Mingw-8.1.0 32bit) ===|
C:\CPPTESTS\main.cpp||In function 'int main()':|
C:\CPPTESTS\main.cpp|136|error: no matching function for call to 'std::__cxx11::basic_istringstream<char, std::char_traits<char>, STLAdaptor<char, CustomAllocator> >::basic_istringstream(std::__cxx11::basic_string<char, std::char_traits<char>, STLAdaptor<char, CustomAllocator> >&, const openmode&, CustomAllocator&)'|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|477|note: candidate: 'std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::basic_istringstream(std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = STLAdaptor<char, CustomAllocator>]'|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|477|note:   candidate expects 1 argument, 3 provided|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|460|note: candidate: 'std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::basic_istringstream(const __string_type&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = STLAdaptor<char, CustomAllocator>; std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::__string_type = std::__cxx11::basic_string<char, std::char_traits<char>, STLAdaptor<char, CustomAllocator> >; std::ios_base::openmode = std::ios_base::openmode]'|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|460|note:   candidate expects 2 arguments, 3 provided|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|442|note: candidate: 'std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::basic_istringstream(std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = STLAdaptor<char, CustomAllocator>; std::ios_base::openmode = std::ios_base::openmode]'|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|442|note:   candidate expects 1 argument, 3 provided|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|425|note: candidate: 'std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::basic_istringstream() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = STLAdaptor<char, CustomAllocator>]'|
C:\MSYS2-32\mingw32\include\c++\10.2.0\sstream|425|note:   candidate expects 0 arguments, 3 provided|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|

查看<sstream> std::basic_istringstream的代碼,似乎不存在來自https://en.cppreference.com/w/cpp/io/basic_istringstream/basic_istringstream 的構造函數 5 到 9,這當然解釋了我的錯誤.

但是如果是這樣,我到底如何用有狀態的自定義分配器構造這樣一個對象?

似乎版本 gcc 10.2 不支持std::basic_istringstream的 C++20 構造函數

在 C++20 正式標准化之前,您可以使用 10.2 之后的 gcc 主干,它支持 C++20 構造函數,因此編譯代碼沒有錯誤:

Live Godbolt 示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM