Beri burada mesele, yani sınıf üzerinde şablonu olan Tyapıcı içinde, Foo(T&&)biz edilir değil tip kesinti yapmak; Her zaman bir r-değeri referansımız vardır. Yani, kurucu Fooaslında şöyle görünür:
Foo(int&&)
Foo(2)çünkü 2bir önkoşul.
Foo(x)çünkü xbağlanamayan bir değerdir int&&. std::move(x)Uygun türe ( demo ) atabilirsiniz.
Foo<int&>(x)yapıcı Foo(int&)referans daraltma kurallarından dolayı olur çünkü iyi çalışır ; başlangıçta standarda göre Foo((int&)&&)çöker Foo(int&).
"Yedekli" kesinti rehberinizle ilgili olarak: Başlangıçta temelde böyle bir yardımcı işlev gibi davranan kod için varsayılan bir şablon kesinti kılavuzu vardır:
template<typename T>
struct Foo {
Foo(T&&) {}
};
template<typename T>
Foo<T> MakeFoo(std::add_rvalue_reference_t<T> value)
{
return Foo<T>(std::move(value));
}
//...
auto f = MakeFoo(x);
Bunun nedeni, standardın bu (kurgusal) şablon yönteminin sınıfla (Just T) aynı şablon parametrelerine ve ardından kurucu ile herhangi bir şablon parametresine sahip olmasını gerektirmesidir (bu durumda hiçbiri; yapıcı şablonlaştırılmaz). Ardından, işlev parametrelerinin türleri yapıcıdakilerle aynıdır. Bizim durumumuzda, somutlaştırıldıktan sonra Foo<int>, kurucu Foo(int&&)başka bir deyişle bir rvalue referansı gibi görünüyor . Dolayısıyla add_rvalue_reference_tyukarıdakilerin kullanımı .
Açıkçası bu işe yaramıyor.
"Yedekli" kesinti rehberinizi eklediğinizde:
template<typename T>
Foo(T&&) -> Foo<T>;
Sen ekli referans her türlü rağmen derleyici o ayırt izin Tyapıcı (içinde int&, const int&ya da int&&vb), sen referans (sadece sensiz olmak sınıfın bilgilerin tahmin türü amaçlanan T). Aniden Bunun nedeni vardır tip çıkarımlar gerçekleştirmek.
Şimdi şöyle görünen başka bir (kurgusal) yardımcı fonksiyon üretiyoruz:
template<class U>
Foo<U> MakeFoo(U&& u)
{
return Foo<U>(std::forward<U>(u));
}
// ...
auto f = MakeFoo(x);
(Yapıcıya yaptığımız çağrılar, sınıf şablonu argümanı kesinti amacıyla yardımcı işlevine yönlendirilir, böylece Foo(x)olur MakeFoo(x)).
Bu veriyor U&&olmak int&ve Tbasitçe olmakint