Amacı nedir std::make_pair
?
Neden sadece std::pair<int, char>(0, 'a')
?
İki yöntem arasında herhangi bir fark var mı?
std::make_pair
gereksizdir. Aşağıda bunu detaylandıran bir cevap var.
Amacı nedir std::make_pair
?
Neden sadece std::pair<int, char>(0, 'a')
?
İki yöntem arasında herhangi bir fark var mı?
std::make_pair
gereksizdir. Aşağıda bunu detaylandıran bir cevap var.
Yanıtlar:
Fark, std::pair
her iki öğenin türünü belirtmeniz gerektiğidir, oysa std::make_pair
ona söylemeniz gerekmeden, kendisine iletilen öğelerin türüyle bir çift oluşturacaktır. Zaten çeşitli belgelerden toplayabiliyordum.
Http://www.cplusplus.com/reference/std/utility/make_pair/ adresinden bu örneğe bakın.
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Örtük dönüşüm bonusunun yanı sıra, make_pair kullanmadıysanız yapmanız gerekir
one = pair<int,int>(10,20)
birine atadığınız her seferinde zamanla sinir bozucu olurdu ...
std::make_pair
. Görünüşe göre sadece kolaylık sağlamak için.
one = {10, 20}
Bugünlerde yapabileceğinizi düşünüyorum ama kontrol etmek için kullanışlı bir C ++ 11 derleyici yok.
make_pair
, yapılar, birlikler, lambdalar ve diğer doodadlar dahil olmak üzere adsız türlerle çalıştığını unutmayın .
@MSalters yukarıda yanıtlandığı gibi, artık bunu C ++ 11'de yapmak için kıvırcık parantezleri kullanabilirsiniz (bunu sadece bir C ++ 11 derleyicisiyle doğrulayın):
pair<int, int> p = {1, 2};
C ++ 17'den önce sınıf şablonu bağımsız değişkenleri yapıcıdan çıkarılamadı
C ++ 17'den önce şöyle bir şey yazamazdınız:
std::pair p(1, 'a');
çünkü şablon türlerini yapıcı argümanlarından çıkarır.
C ++ 17 sözdizimini mümkün kılar ve bu nedenle make_pair
gereksizdir.
C ++ 17'den önce, std::make_pair
daha az ayrıntılı kod yazmamıza izin verdi:
MyLongClassName1 o1;
MyLongClassName2 o2;
auto p = std::make_pair(o1, o2);
daha ayrıntılı yerine:
std::pair<MyLongClassName1,MyLongClassName2> p{o1, o2};
hangi türleri tekrarlar ve çok uzun olabilir.
Yapımcı olmadığı için tür çıkarımı o C ++ 17 öncesi durumda çalışır make_pair
.
make_pair
aslında aşağıdakilere eşdeğerdir:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2) {
return std::pair<T1, T2>(t1, t2);
}
Aynı kavram inserter
vs için de geçerlidir insert_iterator
.
Ayrıca bakınız:
Minimal örnek
İşleri daha somut hale getirmek için, sorunu en az şekilde gözlemleyebiliriz:
main.cpp
template <class MyType>
struct MyClass {
MyType i;
MyClass(MyType i) : i(i) {}
};
template<class MyType>
MyClass<MyType> make_my_class(MyType i) {
return MyClass<MyType>(i);
}
int main() {
MyClass<int> my_class(1);
}
sonra:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
mutlu bir şekilde derler, ancak:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
ile başarısız:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
ve bunun yerine çalışmak gerekir:
MyClass<int> my_class(1);
veya yardımcı:
auto my_class = make_my_class(1);
bir yapıcı yerine normal bir işlev kullanır.
Std :: reference_wrapper için fark
Bu yorum , kurucu std::make_pair
yapmazken açılmasından bahsediyor std::reference_wrapper
, bu yüzden bu bir fark. YAPILACAKLAR örneği.
GCC 8.1.0, Ubuntu 16.04 ile test edilmiştir .
std::make_pair
C ++ 17'de kullanımdan kaldırılmadı?
make_pair
referans paketleyicilerini açar, bu yüzden aslında CTAD'den farklıdır.
make_pair
Yapıcıyı pair
belirtilen tür bağımsız değişkenleriyle kullanma ve açıkça çağırmak arasında bir fark yoktur . std::make_pair
türler ayrıntılı olduğunda daha kullanışlıdır, çünkü bir şablon yönteminde verilen parametrelere dayalı tür kesinti vardır. Örneğin,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
Bunun C ++ şablon programlamasında yaygın bir deyim olduğunu belirtmek gerekir. Object Generator deyimi olarak bilinir, daha fazla bilgi ve güzel bir örnek burada bulabilirsiniz .
Düzenle Yorumlarda önerildiği gibi (kaldırıldığından beri), kopması durumunda aşağıdaki bağlantıdan biraz değiştirilmiş bir alıntıdır.
Bir Nesne Oluşturucu, türlerini açıkça belirtmeden nesnelerin oluşturulmasına izin verir. Sınıf şablonlarının sahip olmadığı işlev şablonlarının kullanışlı bir özelliğini temel alır: Bir işlev şablonunun tür parametreleri, gerçek parametrelerinden otomatik olarak çıkarılır. işlevin gerçek parametrelerine bağlı olarak şablonun std::make_pair
bir örneğini döndüren basit bir örnektir .std::pair
std::make_pair
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
{
return std::pair <T, U> (t,u);
}
&&
C ++ 11'den beri.
make_pair doğrudan kurucu üzerinden fazladan bir kopya oluşturur. Basit sözdizimi sağlamak için her zaman çiftlerimi yazıyorum.
Bu farkı gösterir (örnek Rampal Chaudhary tarafından):
class Sample
{
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
}
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
}
~Sample()
{
std::cout<<"Destroying object "<<_objectNo<<std::endl;
}
};
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
{
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
}
std::move
sadece içeride insert
ve / veya neye referans olacağı konusunda sample
. Ben değiştirmek zaman sadece std::map<int,Sample>
için std::map<int,Sample const&>
ben inşa nesnelerin sayısını azaltmak olduğunu ve sadece ben tüm kopyaları (tabii ki) ortadan kaldırmak olduğunu kopya kurucu sildiğinizde. Bu değişikliklerin her ikisini de yaptıktan sonra, sonucum varsayılan yapıcıya bir çağrı ve aynı nesne için yıkıcıya iki çağrı içeriyor. Sanırım bir şey eksik olmalıyım. (g ++ 5.4.1, c ++ 11)
emplace
bunun yerine tavsiye ederim insert
. Benim uzmanlık alanım değil, bir tane olduğunu söyleyebilirim, ancak kopyala / taşı C ++ 11 tarafından sunulan anlambilim bana çok yardımcı oldu.
c ++ 11'den başlayarak sadece çiftler için tek tip başlatma kullanın. Bunun yerine:
std::make_pair(1, 2);
veya
std::pair<int, int>(1, 2);
sadece kullan
{1, 2};
{1, 2}
bir çifti başlatmak için kullanılabilir, ancak tip çiftini taahhüt etmez. Yani otomatik kullanırken RHS: üzerinde bir tür taahhüt gerekir auto p = std::pair{"Tokyo"s, 9.00};
.