2016-01-15 16 views
5

znajdę kilka słów tutaj http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor/constructstd :: scoped_allocator_adaptor i klasa z użyciem konstruktora std :: allocator_arg_t

jeśli std::uses_allocator<T, inner_allocator_type>::value==true (typ T wykorzystuje podzielników, na przykład jest to pojemnik)

a jeśli std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true,

następnie wywołuje

std::allocator_traits<OUTERMOST>::construct(OUTERMOST(*this), 
              p, 
              std::allocator_arg, 
              inner_allocator(), 
              std::forward<Args>(args)...); 

Więc robię prosty test

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); 
} 

ale gcc i brzęk dać mi te błędy https://gist.github.com/anonymous/3e72754a7615162280fb

piszę również use_a zastąpić use_arg. Mogłoby się to udać.

struct use_a { 
    template <typename Alloc> 
    use_a(int i, Alloc &) { std::cout << i << " in use_a()\n"; } 
}; 

Co sprawia, że ​​te zachowania się zdarzają?

Odpowiedz

3

Myślę, że zarówno libstdC++, jak i libC++ robią dokładnie to, czego standard wymaga dla przykładu OP.

uses_allocator<use_arg, allocator<use_arg>> to prawda, ale is_constructible<use_arg, allocator_arg_t, inner_allocator_type, int> jest fałszywe, ponieważ nie jest use_arg constructible z podzielnika rvalue, więc wywołanie construct powinny być źle sformułowane.

Jednak uważam, że jest to usterka standardu. Rozważmy ten typ:

struct use_arg { 
    using allocator_type = std::allocator<use_arg>; 
    use_arg(allocator_type&&) { } 
}; 

W uses_allocator i is_constructible cechy są zarówno prawdziwe, ale wzywa do scoped_allocator_adaptor::construct(pointer) nie uda się skompilować.

Nie można sprawdzić, czy is_constructible<T, inner_allocator_type> (który testuje konstrukcję z przydziału wartości), ale następnie przekazać inner_allocator_type& (co stanowi lwartość), ale tak mówi standard.

1

Problem polega na tym, że użytkownik otrzymuje Alloc przez odniesienie.

std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true 

tutaj w przypadku inner_allocator tylko std::scoped_allocator_adaptor<std::allocator<use_arg>> i nie mogą być zamienione na std::scoped_allocator_adaptor<std::allocator<use_arg>>&. Możesz po prostu otrzymać wartość Alloc lub przez const-reference.

+0

Co z 'std :: is_constructible >> :: value'? Jest również "false", ale może konstruować. – linux40

+0

@ linux40, który wygląda jak błąd, ponieważ na przykład w klangu, nie ma tego czeku, sprawdzana jest tylko wartość uses_allocator ::. – ForEveR

+0

jest tylko jedno zaznaczenie w gcc również. – ForEveR

Powiązane problemy