重载函数时使用临时对象作为参数是一种好的做法吗
Is it a good practice to use temporary objects as arguments when overloading functions?
给定原型:
void foo(int i);
void foo(int i, const std::string &s);
实施:
void foo(int i)
{
foo(i, std::string()) ;
//! ^^^^^^^^^^^^^ ^ here?
// nothing more.
}
//! ^ here?
void foo(int i, const std::string &s)
{
//do something
}
std::string()
创建的临时对象在哪里超出范围?以这种方式使函数过载是一种好的做法吗?
更新:
让我解释一下情况。作为练习,我尝试在不使用模板的情况下编写一个类似std::vector
的类。它持有的唯一类型是std::string
。类主体可以在另一个问题中找到。
在实现resize()
成员函数时,我发现std::vector
似乎使用了两个函数:
void
resize(size_type __new_size);
void
resize(size_type __new_size, const value_type& __x);
所以我想知道我是否应该使用两个函数而不是一个函数。
不,这不是一个好的做法,至少在这种特殊情况下是这样。使用单个函数和参数的默认值,而不是两个函数,其中一个函数似乎只提供默认参数:
void foo(int i, const std::string &s = "")
{
//do something
}
我不认为这是一种糟糕的做法,尤其是如果您使foo(int i)
内联。我可以想到这样做的原因:当您创建指向函数的指针时,如果您声明第二个参数为default,则只能有指向接受2个参数的函数的指针。
临时值仅作为函数调用的参数才有效。
inline void foo(int i)
{
foo(i, std::string());
}
void foo(int i, const std::string &s)
{
//do something
}
如果函数创建了一个对象,该对象在函数调用中幸存下来,并在自身存储了const&
,则传递临时的asconst&
的唯一"危险"就会发生。
思考
class A
{
const string& a;
public:
A(const string& a) :a(a) {}
void act() { .... /* use a */ }
};
A* foo(const string& s)
{ return new A(s); }
int main()
{
A* pa = foo(string());
//here, pa->act() will act on a dangling reference.
}
如果foo
函数只是使用字符串,但不保留引用供以后使用,那么传递临时函数是完全安全的。
如果使用"引导函数"或默认临时值发生这种情况,则对生成的代码没有任何影响。
在这一点上,使用一个或两个函数更多的是一个风格和机会的问题:在进一步的开发过程中,这两个函数有多少机会区分开来?
如果答案是"none:第二个函数只是非常频繁情况下的定义(或快捷方式)",那么默认值就可以完美地完成任务。
如果答案是"让我们现在回到另一个函数,稍后更具体",那么两个函数是首选的。
然而,如果函数是模板,并且您希望类型推导起作用,则默认值是不可能的:
template<class C, class T>
void fn(int i, basic_string<C,T>& s = ????);
您不能使用std::string(),因为它不适用于char
以外的C
,也不能使用std::basic_string<C,T>()
,因为它将不允许在fn(5)
调用时推断C和T应该是什么。
所以你最终会得到
void fn(int i) { fn(i,string()); }
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 构造函数是否有一种现代C++方法来了解其'container'类?
- 有没有一种简单的方法可以在对象向量上调用构造函数?
- 有没有一种简单的方法来调用带有默认参数的函数?
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 在C++中,有没有一种方法可以让我在不传递参数的情况下拥有一个函数
- 有没有一种方法可以在linux中扫描已构建的ARM库中的函数
- 有没有一种方法可以获得传递给函数的数组的大小
- 常量静态成员函数:有另一种方法可用吗?
- C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
- 是否有一种方法可以调用一个函数,而不会创建变量,而不会创建变量
- 有没有一种单行方法来调用集合上的 lambda 函数
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?
- 是否有一种方法可以在超载运算符函数中接触默认运算符函数
- 是否有一种方法可以避免标头文件中使用的constexpr函数输入全局范围,而无需额外的名称空间
- 是否可以将一种函数类型转换为另一种采用相同参数但返回类型不同的函数类型
- 是c++模板元编程的一种函数编程形式