在现代C++中,在函数声明中定义返回变量是否合法?

Har*_*rry 40 c++ declaration language-lawyer

我在CodeSignal上发现了一段奇怪的C++语法:

string r, longestDigitsPrefix(string s)
{
   for(auto const c : s)
   {
      if(isdigit(c))
        r += c;
      else
        break;
   }
   return r;
}
Run Code Online (Sandbox Code Playgroud)

第一行是string r在函数声明之前定义的.这在现代C++中是否有效?

上面的代码编译并传递CodeSignal控制台中的所有测试,但是当我尝试本地编译时它产生了编译器错误(--std=c++14).

这是现代C++中的有效语法吗?如果是这样,它符合哪个标准修订版?

Bar*_*rry 54

是的,C++语法很奇怪.基本上,当涉及到声明(并且只是声明)时,我们有以下内容:

T D1, D2, ... ,Dn;
Run Code Online (Sandbox Code Playgroud)

表示([dcl.dcl]/3):

T D1;
T D2;
...
T Dn;
Run Code Online (Sandbox Code Playgroud)

这在正常情况下会很熟悉:

int a, b; // declares two ints
Run Code Online (Sandbox Code Playgroud)

并且可能在您被告知担心的情况下:

int* a, b, *c; // a and c are pointers to int, b is just an int
Run Code Online (Sandbox Code Playgroud)

但是声明者也可以引入其他东西:

int *a, b[10], (*c)[10], d(int);
Run Code Online (Sandbox Code Playgroud)

a是一个指向int的指针,b是一个10 int秒的数组,c是一个指向10 int秒数组的指针,d是一个int返回的函数int.


但是,这适用于声明.所以这:

string r, longestDigitsPrefix(string s);
Run Code Online (Sandbox Code Playgroud)

是一个有效的C++声明,它声明r是一个string并且longestDigitsPrefix是一个带a string和返回a 的函数string.

但是这个:

string r, longestDigitsPrefix(string s) { return s; }
Run Code Online (Sandbox Code Playgroud)

是无效的C++.函数定义有自己的语法,不能作为init-declarator-list的一部分出现.

该函数的定义也很糟糕,因为它使用全局变量来跟踪状态.因此,即使它是有效的,longestDigitsPrefix("12c")也会"12"在第一次返回,但"1212"第二次返回......

  • 逗号运算符可以用作*表达式*的一部分,但是这里提出的代码在语法上不是表达式(它是*语句*),所以我认为不需要在反驳中查看逗号运算符这在语法上是正确的. (13认同)

小智 -4

据我所知,这不是有效的函数声明。

函数中的前缀只能用作定义函数“返回”变量的类型,而不是变量本身的类型。

但是,您可以在函数外部声明一个变量(从而使其成为全局变量)并在函数内部修改它,就像您可能尝试过的那样,但是您需要将所述变量作为函数参数中的引用传递。您还需要将函数设置为 void,因为它不会返回变量,而只是修改它

例子

std::string foo = "Hello";

void foo_func(std::string &string)
{ //do something with the string
}

//call the function and modify the global "foo" string
foo_func(foo);
Run Code Online (Sandbox Code Playgroud)

  • 由于该问题具有“语言律师”标签,因此我们期望答案带有 C++ 标准引号。 (3认同)