C++ 作用域分配程序似乎要求默认构造分配程序

C++ 作用域分配程序似乎要求默认构造分配程序,c++,c++11,templates,stl,allocator,C++,C++11,Templates,Stl,Allocator,在我对作用域分配程序适配器的实验中,我试图将从main(..)获得的分配程序传递到S1的构造函数中(更一般地说,S1中会有多个不同的类型,它们都使用构造函数中提供的分配程序)。然而,我得到下面的编译错误,表明分配器应该是默认可构造的。有人能解释一下为什么会这样吗?是否发生了一些转换,导致需要默认构造的分配器版本 #include <iostream> #include <cassert> #include <vector> #include <scope

在我对作用域分配程序适配器的实验中,我试图将从main(..)获得的分配程序传递到S1的构造函数中(更一般地说,S1中会有多个不同的类型,它们都使用构造函数中提供的分配程序)。然而,我得到下面的编译错误,表明分配器应该是默认可构造的。有人能解释一下为什么会这样吗?是否发生了一些转换,导致需要默认构造的分配器版本

#include <iostream>
#include <cassert>
#include <vector>
#include <scoped_allocator>

// Move allocator and container aliases into namepsace 
namespace custom
{
    template <typename T>
    struct MyAlloc
    {
        using value_type = T;
        MyAlloc(const std::string &scope) noexcept : _scope(scope)  {} 

        // Rebinding allocatos to different type 
        template <class U> 
        MyAlloc(const MyAlloc<U> & other) noexcept : _scope(other._scope)  {}

        // Allow for move operations to be noexcept
        //using is_always_equal = std::true_type;

        value_type*  allocate(std::size_t n) noexcept
        {
            std::cout << "Allocating " << n << " objects within " << _scope << " from " << __PRETTY_FUNCTION__ << std::endl;
            return static_cast<value_type*>(::operator new (n*sizeof(value_type)));
        }
        void deallocate(value_type* p, std::size_t n) noexcept
        {
            std::cout << "Deallocating " << n << " objects within " << _scope << " from " << __PRETTY_FUNCTION__ << std::endl;
            ::operator delete(p);
        }
        std::string _scope;
    };

    // Allocators compare equal to enable one allocator to de-allocate memory
    // from another
    template <typename T>
    bool operator==(const MyAlloc<T> &x1, const MyAlloc<T> &x2) noexcept
    {
        return true;
    }

    template <typename T>
    bool operator!=(const MyAlloc<T> &x1, const MyAlloc<T> &x2) noexcept
    {
        return !(x1 == x2);
    }

    template <typename T>
    using allocator = std::scoped_allocator_adaptor<MyAlloc<T>>;

    template <typename T> //  adaptor to propagate
    using vector = std::vector<T, allocator<T>>;

    template <typename T> 
    using bstr = std::basic_string<T, std::char_traits<T>, allocator<T>>;
    using string = bstr<char>;
}

struct S1
{
   using allocator_type = custom::allocator<std::byte>;
   S1(allocator_type alloc) : str("This is a very long string indeed..", std::allocator_traits<allocator_type>::rebind_alloc<char>(alloc))
   {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
   }
   S1(const S1 &other, allocator_type al)  : str(other.str, std::allocator_traits<allocator_type>::rebind_alloc<char>(al))
   {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
   }
   custom::string str;
};



int main()
{
   custom::allocator<std::byte> sc{"scope"};
   custom::vector<S1> cv{sc};
//   cv.emplace_back();
}
#包括
#包括
#包括
#包括
//将分配器和容器别名移到namepsace中
命名空间自定义
{
模板
结构MyAlloc
{
使用值_type=T;
MyAlloc(const std::string&scope)noexcept:u scope(scope){}
//将分配器重新绑定到不同类型
模板
MyAlloc(const MyAlloc&other)无例外:_范围(other._范围){}
//允许移动操作不例外
//使用is_always_equal=std::true_类型;
值类型*分配(标准::大小)无例外
{

std::cout这一行:
custom::vector cv{sc};
是问题所在

因为您使用了方括号,所以它试图调用
vector
s初始值设定项列表构造函数,该构造函数有一个可选参数,它是一个分配器,它默认构造一个分配器

请参阅中的最后两个构造函数

如果您将该行更改为
custom::vector cv(sc);
它将编译为w/o错误

/usr/include/c++/10/scoped_allocator: In instantiation of ‘std::scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs>::scoped_allocator_adaptor() [with _OuterAlloc = custom::MyAlloc<S1>; _InnerAllocs = {}]’:
/usr/include/c++/10/bits/stl_vector.h:626:35:   required from here
/usr/include/c++/10/scoped_allocator:304:60: error: no matching function for call to ‘custom::MyAlloc<S1>::MyAlloc()’
  304 |       scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { }
      |                                                            ^
d2.cc:17:9: note: candidate: ‘template<class U> custom::MyAlloc<T>::MyAlloc(const custom::MyAlloc<U>&) [with U = U; T = S1]’
   17 |         MyAlloc(const MyAlloc<U> & other) noexcept : _scope(other._scope)  {}
      |         ^~~~~~~
d2.cc:17:9: note:   template argument deduction/substitution failed:
In file included from d2.cc:4:
/usr/include/c++/10/scoped_allocator:304:60: note:   candidate expects 1 argument, 0 provided
  304 |       scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { }
      |                                                            ^
d2.cc:13:9: note: candidate: ‘custom::MyAlloc<T>::MyAlloc(const string&) [with T = S1; std::string = std::__cxx11::basic_string<char>]’
   13 |         MyAlloc(const std::string &scope) noexcept : _scope(scope)  {}
      |         ^~~~~~~
d2.cc:13:9: note:   candidate expects 1 argument, 0 provided
d2.cc:10:12: note: candidate: ‘custom::MyAlloc<S1>::MyAlloc(const custom::MyAlloc<S1>&)’
   10 |     struct MyAlloc
      |            ^~~~~~~
d2.cc:10:12: note:   candidate expects 1 argument, 0 provided
d2.cc:10:12: note: candidate: ‘custom::MyAlloc<S1>::MyAlloc(custom::MyAlloc<S1>&&)’
d2.cc:10:12: note:   candidate expects 1 argument, 0 provided