Jak wiem std::allocator<T>::construct
bierze tylko dwa parametry w starszej wersji C ++; pierwszy to wskaźnik do surowej, nieskonstruowanej pamięci, w której chcemy zbudować obiekt typu, T
a drugi to wartość typu elementu w celu zainicjowania tego obiektu. Tak więc wywoływany jest konstruktor kopii:
struct Foo {
Foo(int, int) { cout << "Foo(int, int)" << endl; }
/*explicit*/ Foo(int) { cout << "Foo(int)" << endl; }
Foo(const Foo&) { cout << "Foo(const Foo&)" << endl; }
};
int main(int argc, char* argv[]) {
allocator<Foo> a;
Foo* const p = a.allocate(200, NULL); // second parameter is required on C++98 but on C++11 it is optional
// Foo* const p = a.allocate(200); // works fine on C++11 but not on C++98
a.construct(p, 5, 7); // works on C++ 11 and up but not C++98
a.construct(p, 10);// works on both
a.destroy(p);
a.destroy(p + 1);
a.deallocate(p, 200);
std::cout << std::endl;
}
Dlaczego w C ++ 98
a.construct(p, 10)
wywoływanie konstruktora kopiowania, a w C ++ 11 i nowszych wywołuje tylko konstruktor, który przyjmuje liczbę całkowitą?Czy to znaczy, na C ++ 11 z powodu jakiejś optymalizacji kopiowaniem elizja nawet jeśli konstruktor
Foo(int)
jestexplicit
działa na takiej rozmowy:a.construct(p, 5)
prace nad C ++ 11 nawet konstruktor jestexplicit
kim jestem pewien czy to nie działa w C ++ 98, jeśliFoo(int)
jestexplicit
.Jeśli tak, to jeśli skompiluję tę instrukcję z pewnym wyłączeniem
copy-elision
optymalizacji spowoduje kompilator się nie powiedzie? Dziękuję Ci.
Odpowiedzi:
Wynika to z faktu, że deklaracja
construct
zmiany w C ++ 11 :Pierwsza deklaracja wywołuje konstruktor kopiowania, a druga deklaruje konstruktor pasujący do podanej listy argumentów. Może to być konstruktor kopii, ale także inny konstruktor, jak widzieliście w kodzie.
a.construct(p, 10)
wywołuje konstruktor kopiowania w C ++ 98, ponieważ10
jest on domyślnie konwertowanyFoo
naFoo(int)
konstruktor. Ta konwersja nie jest konieczna w C ++ 11, ponieważ istnieje zgodny konstruktor, który pobieraint
(dokładnie konstruktor użyty do konwersji w C ++ 98). Jest to również powód, dla którego kod nie działa w C ++ 98 po dodaniuexplicit
- nie może przekonwertować10
go naFoo
wtedy.źródło