SORU
4 Kasım 2012, Pazar


Genellikle/her zaman std kullanabilir miyim::std yerine ileri gitmek mi?

Scott Meyers'in ve Ötesi 2012 C Konferansı talk on Universal References, ve şu ana kadar her şey mantıklı. izliyorum Ancak, bir seyircinin de merak ediyordum o da yaklaşık 50 dakikalık bir soru sorar. Meyers olmayan deyimsel çünkü cevap umurunda olmadığını söylüyor ve onun aptal bir sakıncası var, ama yine de ilgileniyorum.

Kod sunulan aşağıdaki gibidir:

// Typical function bodies with overloading:
void doWork(const Widget& param)   // copy
{
  // ops and exprs using param
}
void doWork(Widget&& param)        // move
{
  // ops and exprs using std::move(param)
}

// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param)             // forward => copy and move
{
  // ops and exprs using std::forward<T>(param)
}

Nokta rvalue başvurusu attığımızda, bir rvalue biz biliyoruz, std::move bir rvalue aslında korumamız gerekiyor. Ne zaman biz bir evrensel referans (T&& nereye T çıkarılabilir tip), istiyoruz std::forward korumak aslında bu olabilir bir lvalue veya bir rvalue.

Şimdi soru şu: beri std::forward korur değeri olmadığını kabul işlevi ya da bir lvalue veya bir rvalue ve std::move sadece atan bağımsız bir rvalue, sadece std::forward her yerde? std::forward std::move, biz her durumda std::move gibi davranır ya Meyers tarafından kaçırılmış olan davranış' genelleme? bazı önemli farklılıklar vardır

Herkes Meyers doğru söylediği gibi, olmayan deyimsel tamamen çünkü, Ama şu da std::move geçerli bir kullanım: yapması gerektiğini düşündüren değilim

void doWork(Widget&& param)         // move
{
  // ops and exprs using std::forward<Widget>(param)
}

CEVAP
4 Kasım 2012, Pazar


İkisi çok farklıtamamlayıcıaraçlar.

  • std::moveşüpheleribağımsız ve koşulsuz rvalue bir ifade oluşturur. Bu anlamda gerçek bir nesne veya değişken uygulamak için yapar.

  • std::forward zorunlu şablon bağımsız değişken (bu belirtmeniz gerekir!) alır ve sihirli bir şekilde lvalue başvuru veya rvalue bir ifade türü ne bağlı olarak (&& ve çöken kuralları ekleme gereği) oluşturur. Bu sadece mantıklı bir çıkarım, şablonu esas alan bir işlev bağımsız değişkeni için uygulamak için yapar.

Belki aşağıdaki örnekler, bu biraz daha iyi göstermek:

#include <utility>
#include <memory>
#include <vector>
#include "foo.hpp"

std::vector<std::unique_ptr<Foo>> v;

template <typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));  // #1
}

int main()
{
    {
        std::unique_ptr<Foo> p(new Foo('a', true, Bar(1,2,3)));
        v.push_back(std::move(p));                                  // #2
    }

    {
        v.push_back(make_unique<Foo>('b', false, Bar(5,6,7)));      // #3
    }

    {
        Bar b(4,5,6);
        char c = 'x';
        v.push_back(make_unique<Foo>(c, b.ready(), b));             // #4
    }
}

Mevcut durumda, bir beton var #2, p, nesne ve koşulsuz olarak hareket etmek istiyoruz. Sadece std::move mantıklı. Bir şey yok "" burada. ileri var Adında bir değişken var ve bunu taşımak istiyoruz.

Öte yandan, durum #1 argümanlar herhangi bir listesini kabul eder, ve her bir bağımsız değişken orijinal arayın aynı değer kategorisi olarak iletilmesi gerekiyor. Örneğin, #3 geçici değişkenleri ifadeler ve böylece rvalues olarak iletilecek. Ama aynı zamanda durum gibi nesneleri yapıcı çağrısında adlı karma yapabiliriz #4 ve lvalues olarak iletme ihtiyacımız var.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Cartoonium

    Cartoonium

    11 NİSAN 2011
  • DONFANTASTICKYPESS

    DONFANTASTIC

    1 Temmuz 2007
  • RawBrahs

    RawBrahs

    28 Aralık 2010