当前位置:网站首页>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
边栏推荐
猜你喜欢
Mind mapping series - Database
QT realizes message sending and file transmission between client and server
Kaggle 时间序列教程
Must know must know -c language keywords
Embedded hardware - read schematic
Advanced C - Section 2 - pointers
Gradient descent, learning rate
[try to hack] upload labs (temporarily write to 12)
利用Javeswingjdbc基于mvc设计系统
Section 8 - Practical commissioning techniques
随机推荐
Stepping on a horse (one stroke)
Force deduction 121 questions
Kaggle 时间序列教程
2022氯化工艺操作证考试题库及模拟考试
How to use redis
Ctfshow common postures (821-830)
Swiper plug-in
Robot pose description and coordinate transformation
LeetCode第297场周赛(20220612)
Kaggle time series tutorial
D 小红的构造题
rust编程-链表:使用struct实现链表,使用堆合并k个升序链表,自定义Display
Collection of some compatibility issues
rainbow
PostgreSQL Guide: inside exploration (Chapter 10 basic backup and point in time recovery) - Notes
Recommended temporary online image compression tool
你的一对一会议效率低下,你可以这么做!
Avantages de win8.1 et win10
QT realizes message sending and file transmission between client and server
2022年氧化工艺操作证考试题库及模拟考试