1. 简介
- 本文探讨了函数形参的三种写法
- 方法一:
const T&
—— 最常见 - 方法二:
const T&
+T&& + move
- 方法三:
T + move
- 方法一:
- 换句话说
- 写代码的时候,经常会遇到,一个类的成员函数,需要从外部接收一个值,然后存到自己的成员变量里
- 然后关于这个问题,C++里怎么写,效率最高(结合move语义)
2. 实验内容
编译器:
gcc.exe (x86_64-win32-seh-rev1, Built by MinGW-Builds project) 13.1.0
编译命令:
g++ main.cpp -std=c++17 -O3 && .\a.exe
代码1:只实现了
const T&
(最平凡的写法)
using uint = uint32_t;
struct S {
S() { std::cout << "\tS Default" << std::endl; }
S(const S&) { std::cout << "\tS Copy" << std::endl; }
S(S&&) { std::cout << "\tS Move" << std::endl; }
};
struct Node {
Node(const S& t) : m_t(t) { std::cout << "Node Copy" << std::endl; }
// Node(S&& t) : m_t(std::move(t)) { std::cout << "Node Move" << std::endl; }
// Node(S t) : m_t(std::move(t)) { std::cout << "Move" << std::endl; }
S m_t;
};
int main() {
S t;
std::cout << "Start" << std::endl;
Node node1(t);
Node node2(std::move(t));
return 0;
}
/*
输出为:
S Default
Start
S Copy
Node Copy
S Copy
Node Copy
*/代码2:同时实现了
const T&
和T&&
using uint = uint32_t;
struct S {
S() { std::cout << "\tS Default" << std::endl; }
S(const S&) { std::cout << "\tS Copy" << std::endl; }
S(S&&) { std::cout << "\tS Move" << std::endl; }
};
struct Node {
Node(const S& t) : m_t(t) { std::cout << "Node Copy" << std::endl; }
Node(S&& t) : m_t(std::move(t)) { std::cout << "Node Move" << std::endl; }
// Node(S t) : m_t(std::move(t)) { std::cout << "Move" << std::endl; }
S m_t;
};
int main() {
S t;
std::cout << "Start" << std::endl;
Node node1(t);
Node node2(std::move(t));
return 0;
}
/*
输出为:
S Default
Start
S Copy
Node Copy
S Move
Node Move
*/代码3:实现了
T
using uint = uint32_t;
struct S {
S() { std::cout << "\tS Default" << std::endl; }
S(const S&) { std::cout << "\tS Copy" << std::endl; }
S(S&&) { std::cout << "\tS Move" << std::endl; }
};
struct Node {
// Node(const S& t) : m_t(t) { std::cout << "Node Copy" << std::endl; }
// Node(S&& t) : m_t(std::move(t)) { std::cout << "Node Move" << std::endl; }
Node(S t) : m_t(std::move(t)) { std::cout << "Move" << std::endl; }
S m_t;
};
int main() {
S t;
std::cout << "Start" << std::endl;
Node node1(t);
Node node2(std::move(t));
return 0;
}
/*
输出为:
S Default
Start
S Copy
S Move
Move
S Move
S Move
Move
*/
3. 实验结果
总结
编号 内容 实参左值 实参右值 1 只实现了 const T&
Copy Copy 2 同时实现了 const T&
和T&&
Copy Move 3 实现了 T
Copy + Move Move + Move 所以,为了极致的性能,应该同时实现
const T&
和T&&
4. 参考
- C++的函数形参什么时候应该使用右值引用? - 二律背反的回答 - 知乎
https://www.zhihu.com/question/37834703/answer/151976989