当前位置:网站首页>Clause 26: avoid overloading universal reference types
Clause 26: avoid overloading universal reference types
2022-06-13 04:55:00 【CCSUZB】
Consider the following code :
std::multiset<std::string> names; // Global data structure
void logAndAdd(const std::string &name) {
auto now = std::chrono::system_clock::now();
log(now, "logAndAdd");
names.emplace(name); // Add the name to the global data structure
}
std::string petName("Darla");
logAndAdd(petName); // Pass lvalue std::string
logAndAdd(std::string("Persephone")); // Pass the right value std::string
logAndAdd("Patty Dog"); // Pass the right value std::string
In the first call ,logAndAdd The formal parameter of is bound to a variable petName. stay logAndAdd Inside ,name Was passed on to names.emplace, because name It's a left value. , So it was copied into names Of .
The first 2 And the first 3 Calls name Bound to an R-value , because name It's a left value. , So it was copied into names Of ; We can rewrite logAndAdd Let it accept a universal reference :
template<typename T>
void logAndAdd(T &&name) {
auto now = std::chrono::system_clock::now();
log(now, "logAndAdd");
names.emplace(std::forward<T>(name));
}
std::string petName("Darla");
logAndAdd(petName); // Pass lvalue std::string, Copy the lvalue into multiset
logAndAdd(std::string("Persephone")); // Move the right value
logAndAdd("Patty Dog"); // stay multiset Directly construct a std::string object , Instead of copying one st::string Temporary object of type
}
Consider the following scenario , Let's add one logAndAdd The overloaded version of :
typename<typename T>
void logAndAdd(T &&name) {
auto now = std::chrono::system_clock::now();
log(now, "logAndAdd");
names.emplace(std::forward<T>(name));
}
std::string nameFromIdx(int dx);
void logAndAdd(int dx) {
auto now = std::chrono::system_clock::now();
log(now, "logAndAdd");
names.emplace(nameFromIdx(idx)); // Add the name to the global data structure
}
std::string petName("Darla");
logAndAdd(petName); // The following three usages call the formal parameter T&& The overloaded version of
logAndAdd(std::string("Persephone"));
logAndAdd("Patty Dog");
logAndAdd(22); // The formal parameter type called is int Version of
But if the customer makes the following call , Will not compile
short nameIndx;
logAndAdd(nameIdx); // ! error
logAndAdd There are two overloaded versions ,, The formal parameter is T&& The version of will T Derived as short, To produce an exact match . And the formal parameter is int The version of can only match after the type is promoted short Shape parameter , however names Unable to add short Element of type
One way to fill this hole is to write a constructor with perfect forwarding .
class Person{
public:
template<typename T>
explicit Person(T &&n) :name(std::forward<T>(n)){
}
explicit Person(int idx) : name(nameFromIdx(idx)){
}
Person(const Person&& rhs); // The compiler generates a copy constructor
Person(Person &&rhs); // The compiler generates a move constructor
private:
std::string name;
};
C++ Copy constructors and move constructors will be generated by default , If the user makes the following call :
Person p("Nancy");
auto cloneOfP(p);
The above code does not call the copy constructor , Instead, it calls the perfect forwarding constructor . This function is trying to start from a Person Object of type p Set out to initialize another Person Type of object std::string Data members of type . So compilation failed .
The perfect forwarding constructor will become more complex if the integration is involved :
class SpecialPerson : public Person
{
public:
SpecialPerson(const SpecialPerson &rhs) : Person(rhs) {
} // copy constructor , What is called is the perfect constructor of the base class
SpecialPerson(SpecialPerson &&rhs) : Person(std::move(rhs)){
} // move constructor , What is called is the perfect constructor of the base class
};
The final code did not compile , because std::string Not accepted SpecialPerson Type parameters
边栏推荐
- Implementation of homepage header function in PHP development blog system
- Explain the role of key attribute in V-for
- Logical point
- Section 4 - arrays
- Embedded hardware: electronic components (1) resistance capacitance inductance
- General communication protocol for industrial Internet
- Force buckle 25 A group of K flipped linked lists
- Draw a hammer
- What is the difference between ROM, ram and flash? SRAM、DRAM、PROM、EPROM、EEPROM
- 2022年建筑架子工(建筑特殊工种)特种作业证考试题库及在线模拟考试
猜你喜欢
随机推荐
Several methods of identifying equivalent circuit of circuit drawing
自动评教脚本使用的配置
rust编程-链表:使用struct实现链表,使用堆合并k个升序链表,自定义Display
Spice story
JS to realize the conversion between string and array and an interview question
E - Lucky Numbers
Third party comment plugin
Hidden implementation and decoupling, knowing Pimpl mode
Mysql8.0.13 installation tutorial (with pictures)
Use service worker to preferentially request resources - continuous update
QT client development -- driver loading problem of connecting to MySQL database
JS, how to add grid style
Go/golang connection to database
正态分布(高斯分布)
Design system based on MVC using javeswingjdbc
CMB written test graphical reasoning
Swiper plug-in
Conception d'un système basé sur MVC avec javaswing JDBC
Four methods for judging JS data types and user-defined methods
Advanced C - Section 3 - character functions and string functions









