std::scoped_allocator_adaptor 和一个 class 以及一个使用 std::allocator_arg_t 的构造函数
std::scoped_allocator_adaptor and a class with a constructor using std::allocator_arg_t
我在这里找到一些词http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor/construct
if std::uses_allocator<T, inner_allocator_type>::value==true
(the type
T uses allocators, e.g. it is a container)
and if
std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true
,
then calls
std::allocator_traits<OUTERMOST>::construct( OUTERMOST(*this),
p,
std::allocator_arg,
inner_allocator(),
std::forward<Args>(args)... );
所以,我做一个简单的测试
struct use_arg {
template <typename Alloc>
use_arg(std::allocator_arg_t, Alloc &, int i)
{ std::cout << i << " in use_arg()\n"; }
};
namespace std {
template <typename A> struct uses_allocator<use_arg, A>: true_type {};
} // namespace std
void test_scoped()
{
std::scoped_allocator_adaptor<std::allocator<use_arg>> sa;
auto p = sa.allocate(1);
sa.construct(p, 4);
sa.destroy(p);
sa.deallocate(p, 1);
}
但是 gcc 和 clang 给我这些错误 https://gist.github.com/anonymous/3e72754a7615162280fb
我也写use_a
来代替use_arg
。它可以 运行 成功。
struct use_a {
template <typename Alloc>
use_a(int i, Alloc &) { std::cout << i << " in use_a()\n"; }
};
是什么导致了这些行为?
问题是,您通过引用收到 Alloc
。
std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true
这里你的情况 inner_allocator
只是 std::scoped_allocator_adaptor<std::allocator<use_arg>>
并且无法转换为 std::scoped_allocator_adaptor<std::allocator<use_arg>>&
。您可以只按值接收 Alloc
,或按 const-reference
.
我认为 libstdc++ 和 libc++ 都在做标准对 OP 示例的要求。
uses_allocator<use_arg, allocator<use_arg>>
为真,但 is_constructible<use_arg, allocator_arg_t, inner_allocator_type, int>
为假,因为 use_arg
不能从右值分配器构造,所以 construct
调用应该是 ill-formed .
但是,我认为这是标准中的一个缺陷。考虑这种类型:
struct use_arg {
using allocator_type = std::allocator<use_arg>;
use_arg(allocator_type&&) { }
};
uses_allocator
和 is_constructible
特征都为真,但调用 scoped_allocator_adaptor::construct(pointer)
将无法编译。
检查 is_constructible<T, inner_allocator_type>
(从右值分配器测试构造)然后传递 inner_allocator_type&
(这是一个左值)是不一致的,但这就是标准所说的。
我在这里找到一些词http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor/construct
if
std::uses_allocator<T, inner_allocator_type>::value==true
(the type T uses allocators, e.g. it is a container)and if
std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true
,then calls
std::allocator_traits<OUTERMOST>::construct( OUTERMOST(*this), p, std::allocator_arg, inner_allocator(), std::forward<Args>(args)... );
所以,我做一个简单的测试
struct use_arg {
template <typename Alloc>
use_arg(std::allocator_arg_t, Alloc &, int i)
{ std::cout << i << " in use_arg()\n"; }
};
namespace std {
template <typename A> struct uses_allocator<use_arg, A>: true_type {};
} // namespace std
void test_scoped()
{
std::scoped_allocator_adaptor<std::allocator<use_arg>> sa;
auto p = sa.allocate(1);
sa.construct(p, 4);
sa.destroy(p);
sa.deallocate(p, 1);
}
但是 gcc 和 clang 给我这些错误 https://gist.github.com/anonymous/3e72754a7615162280fb
我也写use_a
来代替use_arg
。它可以 运行 成功。
struct use_a {
template <typename Alloc>
use_a(int i, Alloc &) { std::cout << i << " in use_a()\n"; }
};
是什么导致了这些行为?
问题是,您通过引用收到 Alloc
。
std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true
这里你的情况 inner_allocator
只是 std::scoped_allocator_adaptor<std::allocator<use_arg>>
并且无法转换为 std::scoped_allocator_adaptor<std::allocator<use_arg>>&
。您可以只按值接收 Alloc
,或按 const-reference
.
我认为 libstdc++ 和 libc++ 都在做标准对 OP 示例的要求。
uses_allocator<use_arg, allocator<use_arg>>
为真,但 is_constructible<use_arg, allocator_arg_t, inner_allocator_type, int>
为假,因为 use_arg
不能从右值分配器构造,所以 construct
调用应该是 ill-formed .
但是,我认为这是标准中的一个缺陷。考虑这种类型:
struct use_arg {
using allocator_type = std::allocator<use_arg>;
use_arg(allocator_type&&) { }
};
uses_allocator
和 is_constructible
特征都为真,但调用 scoped_allocator_adaptor::construct(pointer)
将无法编译。
检查 is_constructible<T, inner_allocator_type>
(从右值分配器测试构造)然后传递 inner_allocator_type&
(这是一个左值)是不一致的,但这就是标准所说的。