为什么现有的函数参数不能用于评估其他默认参数?

时间:2012-02-05 03:44:30

标签: c++ function compiler-errors language-lawyer default-arguments

我正在编写一个函数foo(),其中const char*作为参数,pBeginpEndfoo()传递一个以空字符结尾的字符串。默认情况下,pEnd指向字符串的\0(最后一个字符)。

void foo (const char *pBegin,
          const char *pEnd = strchr(pBegin, 0))  // <--- Error
{
  ...
}

但是,我在上面的行中收到错误:

error: local variable ‘pBegin’ may not appear in this context

为什么编译器不允许这样的操作?什么是潜在的问题?

4 个答案:

答案 0 :(得分:9)

该标准不仅明确禁止在默认参数表达式中使用其他参数,还解释了原因并给出了一个示例:

  

ISO / IEC 14882:2003(E) - 8.3.6默认参数[dcl.fct.default]

     

9。每次调用函数时都会计算默认参数。   未指定函数参数的评估顺序。   因此,默认情况下不应使用函数的参数   参数表达式,即使它们未被评估。 a的参数   在默认参数表达式之前声明的函数在范围内   并且可以隐藏命名空间和类成员名称。 [实施例:

    int a;
    int f(int a, int b = a);         // error: parameter a
                                     // used as default argument
    typedef int I;
    int g(float I, int b = I(2));    // error: parameter I found
    int h(int a, int b = sizeof(a)); // error, parameter a used
                                     // in default argument
     

-end example] ...

答案 1 :(得分:6)

语言仍然提供了一种方法来实现你想要的 - 使用重载函数:

void foo (const char *pBegin, const char *pEnd)
{
   //...
}

void foo (const char *pBegin)
{ foo(pBegin, strchr(pBegin, 0)); }

答案 2 :(得分:3)

调用函数时,将评估默认参数,但C ++标准未定义评估它们的顺序。这意味着您无法在默认参数中引用其他参数,因为它们可能还没有已知值。

答案 3 :(得分:1)

您不能在默认参数值中使用局部变量。

Quote from here:

  

标准告诉我们默认参数只是一个表达式。   有些事情是不允许的(使用局部变量,使用   关键字'this')但其他任何东西都可以作为默认值   参数。