C++ 为什么现有函数参数不能用于计算其他默认参数?

C++ 为什么现有函数参数不能用于计算其他默认参数?,c++,function,compiler-errors,language-lawyer,default-arguments,C++,Function,Compiler Errors,Language Lawyer,Default Arguments,我正在编写一个函数foo(),它将2const char*s作为参数,pBegin和pEndfoo()被传递一个以null结尾的字符串。默认情况下,pEnd指向字符串的\0(最后一个字符) void foo (const char *pBegin, const char *pEnd = strchr(pBegin, 0)) // <--- Error { ... } 为什么编译器不允许这样的操作?潜在的问题是什么?< P>当函数被调用时,默认参数被计算,但是它们

我正在编写一个函数
foo()
,它将2
const char*
s作为参数,
pBegin
pEnd
foo()
被传递一个以null结尾的字符串。默认情况下,
pEnd
指向字符串的
\0
(最后一个字符)

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

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

< P>当函数被调用时,默认参数被计算,但是它们被评估的顺序不是由C++标准定义的。这意味着您不能在默认参数中引用其他参数,因为它们可能还没有已知值。

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

标准告诉我们默认参数只是一个表达式。 有些事情是不允许的(使用局部变量,使用 关键字“this”)但几乎所有其他内容都可以作为默认值 争论


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

ISO/IEC 14882:2003(E)-8.3.6默认参数[dcl.fct.Default] 九,。每次调用函数时都会计算默认参数。 未指定函数参数的求值顺序。 因此,默认情况下不得使用函数的参数 参数表达式,即使未对其求值。参数 在默认参数表达式之前声明的函数在作用域中 并且可以隐藏命名空间和类成员名称。[示例:

-结束示例]


该语言仍然提供了一种实现您想要的功能的方法—使用重载函数:

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

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

不同的调用约定以不同的顺序推送参数。一些典型的(
cdecl
stdcall
)从右向左推,因此在您的示例中,
pEnd
需要在
pBegin
之前进行评估,我认为这没有意义。。。这里有一个哑剧:最后一个例子可能看起来过于严格。不管a的值是多少,我们都知道sizeof(a)==sizeof(int)。求值顺序的参数不适用,因此可以允许这种情况。但是g++4.8.2会引发预期的错误。我想这是为了保持规则简单。
    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
void foo (const char *pBegin, const char *pEnd)
{
   //...
}

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