在重载函数时使用临时对象作为参数是一个好习惯吗?

时间:2014-01-05 08:29:13

标签: 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)
{
    //do something
}

std::string()创建的临时对象超出范围?以这种方式过载函数是一个好习惯吗?

更新

让我解释一下这种情况。作为练习,我试图在不使用模板的情况下编写类似std::vector的类。它拥有的唯一类型是std::string。可以在another question中找到班级正文。

实现resize()成员函数时,我发现std::vector似乎正在使用两个函数:

  void 
  resize(size_type __new_size);
  void
  resize(size_type __new_size, const value_type& __x);

所以我想知道我是否应该使用两个函数而不是一个函数。

3 个答案:

答案 0 :(得分:3)

不,这不是一个好习惯,至少在这种特殊情况下。使用单个函数和参数的默认值,而不是两个函数,其中一个函数似乎只存在以提供默认参数:

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

答案 1 :(得分:2)

我不认为这是不好的做法,特别是如果你使foo(int i)内联。我可以想到这是首选的原因:当你创建指向函数的指针时,如果你声明第二个参数是default,你只能指向接受2个参数的函数。

临时值仅作为函数调用的参数。

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

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

答案 2 :(得分:1)

如果函数创建了一个在函数调用本身中存活的对象,那么传递临时函数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 = ????);

你不能使用std :: string(),因为它不适用于C以外的char,并且不能使用std::basic_string<C,T>(),因为它不允许在{fn(5)上推断1}}要求知道C和T应该是什么。

所以你最终会用

void fn(int i) { fn(i,string()); }