C++ 重载函数时使用临时对象作为参数是否是一种好的做法?

C++ 重载函数时使用临时对象作为参数是否是一种好的做法?,c++,object-lifetime,C++,Object Lifetime,给定原型: 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) {

给定原型:

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
}

不,至少在这种情况下,这不是一个好的做法。使用单个函数和参数的默认值,而不是两个函数,其中一个函数似乎仅用于提供默认参数:

void foo(int i, const std::string &s = "")
{
    //do something
}

我不认为这是一种不好的做法,特别是如果您使用
foo(inti)
inline。我可以想到这样做的原因:当您创建指向函数的指针时,如果您声明第二个参数为默认值,那么您只能拥有指向接受2个参数的函数的指针

临时值仅作为函数调用的参数处于活动状态

inline void foo(int i)
{
  foo(i, std::string());
}

void foo(int i, const std::string &s)
{
    //do something
}

我不认为这是一种不好的做法,特别是如果您使用
foo(inti)
inline。我可以想到这样做的原因:当您创建指向函数的指针时,如果您声明第二个参数为默认值,那么您只能拥有指向接受2个参数的函数的指针

临时值仅作为函数调用的参数处于活动状态

inline void foo(int i)
{
  foo(i, std::string());
}

void foo(int i, const std::string &s)
{
    //do something
}
传递临时as
const&
的唯一“危险”是,如果函数创建的对象在函数调用本身之后仍然存在,并且在函数调用本身中存储了
const&

考虑

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
函数只使用字符串,但不保留引用供以后使用,则传递临时值是完全安全的

如果使用“引导函数”或默认临时值发生这种情况,则结果代码不会有任何差异

在这一点上,使用一个或两个函数更多的是风格和机会的问题:在进一步的开发过程中,两个函数有多少机会区分开来

如果答案是“无:第二个函数只是一个非常常见的情况的定义(或快捷方式)”,那么默认值可以完美地完成这项工作

如果答案是“现在让我们回到另一个函数,以后再具体一点”,那么两个函数更可取

但是,如果函数是模板,并且您希望使用类型推断,则不可能使用默认值:

template<class C, class T>
void fn(int i, basic_string<C,T>& s = ????);
.

传递临时as
常量&
的唯一“危险”是,如果函数创建的对象在函数调用本身之后仍然存在,并且在函数调用本身中存储了一个
常量&

考虑

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
函数只使用字符串,但不保留引用供以后使用,则传递临时值是完全安全的

如果使用“引导函数”或默认临时值发生这种情况,则结果代码不会有任何差异

在这一点上,使用一个或两个函数更多的是风格和机会的问题:在进一步的开发过程中,两个函数有多少机会区分开来

如果答案是“无:第二个函数只是一个非常常见的情况的定义(或快捷方式)”,那么默认值可以完美地完成这项工作

如果答案是“现在让我们回到另一个函数,以后再具体一点”,那么两个函数更可取

但是,如果函数是模板,并且您希望使用类型推断,则不可能使用默认值:

template<class C, class T>
void fn(int i, basic_string<C,T>& s = ????);

.

在这种情况下,似乎确实如此。您可能想说
std::string()
而不是
”,以防实现碰巧为空文本分配内存。@meagar Hi!我已经更新了线程。我同意他不需要重载,但如果提供了默认参数,此解决方案中仍然存在临时对象。在这种情况下,它似乎确实存在。您可能想说
std::string()
,而不是
”,以防实现为空文本分配内存。@meagar Hi!我已经更新了线程。我同意他不需要重载,但是如果提供了默认参数,这个解决方案中仍然存在临时对象。如果不理解预期的语义,就不可能给出一个好的答案。如果两个
foo
都做了同样的事情,给它们取相同的名字是有意义的,那么为什么取较少参数的一个需要调用取较多参数的一个,然后再做更多的事情呢?这些东西是琐碎的(日志记录?)还是界面的可见部分,比如一个
foo
做了一些外部理解为与另一个不同的事情?通过编辑,关于生存期的问题没有多大意义。@DavidSchwartz Hi我已经更新了线程。希望它能使情况更清楚。如果不理解预期的语义,就不可能给出一个好的答案。如果两个
foo
都做了同样的事情,给它们取相同的名字是有意义的,那么为什么取较少参数的一个需要调用取较多参数的一个,然后再做更多的事情呢?这些东西是琐碎的(日志记录?)还是界面的一个可见部分,比如一个
foo
做一些事情