Eski yerleşimci :: construct ile yeni olan ve açık kurucu arasındaki fark nedir?


15

Bildiğim gibi std::allocator<T>::constructC ++ eski sürümünde sadece iki parametre alır; birincisi, türünde bir nesne oluşturmak istediğimiz ham, yapılandırılmamış belleğin bir göstergesidir Tve ikincisi, o nesneyi başlatmak için öğe türünün bir değeridir. Böylece kopya oluşturucu çağrılır:

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;
}
  • Neden C ++ 98 a.construct(p, 10)kopyalama yapıcısı çağırıyor ama C ++ 11 ve üzeri sadece bir tamsayı alan yapıcı çağırıyor?

  • Çünkü yapıcı olsa bile bazı Kopya elision optimizasyonu 11 C ++ bu anlamına mı geliyor Foo(int)ise explicitbu tür çağrı çalışır: a.construct(p, 5)C eserler ++ 11 hatta yapıcı olduğunu explicito ++ 98 ise C çalışır vermez değildir eminim neyi Foo(int)olduğunu explicit.

  • Eğer öyleyse ben bu deyimi bir tür copy-elisionoptimizasyon devre dışı bırakma ile derlerseniz derleyici başarısız olur? Teşekkür ederim.


3
Kısa cevap: C ++ 11'e kadar mükemmel bir fowarding yoktu . Ayrıntılar aşağıda @flyx tarafından sağlanmıştır. Herhangi bir kopya elüsyonu olmadığını unutmayın (değere göre geçiş veya değere göre dönüş).
Daniel Langr

Yanıtlar:


13

Bunun nedeni construct C ++ 11'de bildirimin değişmiş olmasıdır :

void construct( pointer p, const_reference val );  (1)  (until C++11)
template< class U, class... Args >
void construct( U* p, Args&&... args );            (2)  (since C++11)

İlk bildirim kopyalama yapıcısını çağırırken, ikinci bildirim verilen bağımsız değişken listesiyle eşleşen bir yapıcıyı çağırır. Bu, kopya oluşturucu olabilir, ancak kodunuzda gördüğünüz başka bir kurucu da olabilir.

a.construct(p, 10)çünkü 98 C ++ kopya kurucu çağırır 10örtülü dönüştürülür Fooaracılığıyla Foo(int)yapıcısı. Bu dönüşüm C ++ 11'de gerekli değildir, çünkü eşleşen bir yapıcı vardır int(tam olarak C ++ 98'de dönüştürmek için kullanılan yapıcı). Bu aynı zamanda eklerken kodu 98 C ++ işi yapmaz nedeni budur explicit- bu dönüştüremezsiniz 10bir karşı Fooo zaman.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.