【问题标题】:variable declaration in function return type specifier c++type函数返回类型说明符中的变量声明 c++type
【发布时间】:2017-04-17 06:53:02
【问题描述】:

我在试用 codefights.com 并注意到有人回答了一个问题,该问题涉及在向量中给出所有最长的字符串:

std::vector<std::string> r, allLongestStrings(std::vector<std::string> a) {
    int b=0;
    for (s:a) if (s.size()>b) b=s.size();
    for (s:a) if (s.size()==b) r.push_back(s);
    return r;
}

他在函数的返回类型说明符中声明了一个变量,谁能告诉我为什么允许这样做?我没有在我的机器上编译,也找不到执行此操作的 gcc 扩展,在此先感谢:)。

【问题讨论】:

  • 您确定该解决方案有效吗?正如所写,这似乎不是有效的 C++。
  • 在任何情况下都不是有效的 C++。某些版本的 GCC 允许这种形式的 ranged-for,但后来因为标准禁止它而被删除。至于在返回类型中声明一个变量……什么?
  • 我知道!,for循环也让我感到困惑,但它在codefights网站上工作并通过了所有测试:S
  • 我会说意图是std::vector&lt;std::string&gt; r; std::vector&lt;std::string&gt; allLongestStrings(......);

标签: c++ gcc gcc-extensions


【解决方案1】:

查看reference (decl-specifier-seq),我看不出如何在函数名之前声明返回变量。

使用 C++14,您可以使用 auto 关键字来删除重复提及的返回类型:

auto allLongestStrings( const std::vector<std::string>& a ) {
    std::vector<std::string> r;
    std::size_t b = 0;
    for( const auto& s : a ) if( s.size() > b ) b = s.size();
    for( const auto& s : a ) if( s.size() == b ) r.push_back( s );
    return r;
}

我修复了代码的其他一些东西:

  • 为了提高效率,将参数a声明为const引用,这样就不会被复制了
  • b 声明为std::size_t 以匹配std::vector::size() 的返回类型
  • 在range-for循环中,需要一个类型说明符(即使是auto);添加 const 参考以提高效率

Live demo.

【讨论】:

  • 我认为,这是一个逗号运算符,是对测试单元代码的利用 <.>
【解决方案2】:

混合变量/函数声明似乎没问题,尽管 gcc 抱怨函数定义不应该存在,但我认为在全局范围内没问题。但如果没有给出函数定义,即使在非全局范围内,它也是 100% 有效的语法。此声明只是对相同前导类型的几个项目的常规声明。例如,我们可以声明多个不同类型但具有相同前导的项目,如下所示:

// single line declaration
int i = 0, * p_i = nullptr, ai[2] = {42,42}, geti(void), * * getppi(void);
// the same as
int i = 0;
int * p_i = nullptr;
int ai[2] = {42, 42};
int geti(void);
int ** getppi(void);

所以r 只是std::vector&lt;std::string&gt; 类型的常规变量,后跟返回相同std::vector 类型的函数allLongestStrings。

这种紧凑的申报表存在历史原因。基本上它有助于节省相当多的字节来存储和编译源文件。

for 循环的这种形式可能是在当前形式标准化之前的早期实验性扩展。

【讨论】:

  • 您的示例显示了混合变量声明和函数声明。 OP的代码是把变量声明和函数定义混在一起,这不是一回事,是不允许的。
  • 不,在全局范围内不行。我试图弄清楚他们使用什么包装器,但是失败了,至少所有现代编译器在尝试通过以下方式组合变量声明和函数定义时都会出错逗号......要么他们有非常过时或异国情调的编译器,而且他们的包装器是某种模板,答案被粘贴在其中,或者那里发生了一些非常奇怪的事情
  • IntelCC seems to allow 将函数定义放在全局范围内的变量之后,就像在 OP 的示例中一样。
  • 那么这可能是他们使用的,但它不符合您的回答声称的标准。
  • @interjay 我的回答并没有提出这样的要求,我明确指出只有在没有给出定义时才可以将变量声明与函数声明混合使用。在写否定的 cmets 之前,请考虑重新阅读我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多