使用具有默认值的参考参数是一种良好的做法
Is using a reference parameter with default value good practice?
我有以下代码:
#include <string>
#include <iostream>
void f(const std::string& s = "")
{
std::cout << """ << s << """ << std::endl;
}
int main()
{
std::string s1 = "qwe";
f();
f("asd");
f(s1);
}
有临时参数和没有参数的调用有多糟糕(如果有的话)?
据我所知,这种编译只是因为const引用延长了临时的生命,直到方法结束http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
尝试在s
参数旁边没有const
的情况下编译相同的示例失败。
#include <string>
#include <iostream>
void f(std::string& s = "")
{
std::cout << """ << s << """ << std::endl;
}
int main()
{
std::string s1 = "qwe";
f();
f("asd");
f(s1);
}
编译
g++-5 -O3 -Wall --std=c++11 main.cpp && ./a.out
main.cpp:4:27: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘std::string {aka std::basic_string<char>}’
void f(std::string& s = "")
^
In file included from /usr/include/c++/5/string:52:0,
from main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:2893:7: note: after user-defined conversion: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
main.cpp: In function ‘int main()’:
main.cpp:12:5: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘std::string {aka std::basic_string<char>}’
f();
^
In file included from /usr/include/c++/5/string:52:0,
from main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:2893:7: note: after user-defined conversion: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
main.cpp:4:6: note: in passing argument 1 of ‘void f(std::string&)’
void f(std::string& s = "")
^
main.cpp:13:10: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘std::string {aka std::basic_string<char>}’
f("asd");
^
In file included from /usr/include/c++/5/string:52:0,
from main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:2893:7: note: after user-defined conversion: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
main.cpp:4:6: note: initializing argument 1 of ‘void f(std::string&)’
void f(std::string& s = "")
这不是一种可怕的做法,但通常最好提供重载:
void f(std::string const& s) { std::cout << "\" << s << "\n"; }
void f() { f(""); }
它避免了一些最终会让很多人感到困惑的语言功能。例如,这个打印什么?
struct base { virtual void f(int i = 42) { std::cout << i; } };
struct derived : base { void f(int i = 19) { std::cout << i; }};
int main() { base * b = new derived(); b->f(); }
当您使用默认参数时也会出现歧义错误,而当您使用重载时则不会。
就const引用而言,这其实并不重要。默认值在函数调用的生存期内绑定到引用。真的一点效果都没有。当编译器可以执行某些引用参数无法执行的优化时,使用值可能会得到更好的结果,但通常情况下,这并不值得关注。
当然,这不适用于非常量引用,因为它们不绑定到临时引用。
默认值允许您在没有任何参数的情况下调用函数,因此如果您有时不将参数传递给函数,请使用具有默认值的引用参数,否则就没有必要这样做。
相关文章:
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 是否有一种标准方法来计算两个 asctime() 值之间的天数
- 有没有一种惯用的方法可以在不存储变换或不必要地重新计算的情况下找到数组变换的最小/最大值?
- 有没有一种标准方法可以在C++中获取第 n 个"下一个"浮点值
- 有没有一种简单的方法来调用带有默认参数的函数?
- 是否有一种有效的方法来搜索队列中的关键字并覆盖其值
- 有没有一种方法可以接受数字数组而不接受垃圾值的输入
- 是否有一种方法可以根据派生的可能性值范围限制对象参数
- 有没有一种很好的方法来实现具有默认失败情况的条件类型?
- 是否有一种方法可以在超载运算符函数中接触默认运算符函数
- 移动 l 值参考参数是否是一种不好的做法?
- boost::P rogram_options 一种判断值是从命令行还是 ini 文件的方法?
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 一种无需使用if语句而无需使用阈值的方法
- 是否有一种方法可以访问/解除并找到存储在双指针向量中的元素的值
- 是否有一种方法可以始终通过值(制作副本)而不是在使用类成员函数时通过参考来传递
- 从 r 值引用限定方法返回 r 值引用是否是一种好的做法?
- c++帮助设计类ConstArray和Array,它们表示一种int值的动态数组
- 使用具有默认值的参考参数是一种良好的做法