【问题标题】:vector<int>::iterator inside if statement fails to compileif 语句中的 vector<int>::iterator 无法编译
【发布时间】:2013-07-29 18:14:27
【问题描述】:

我有两个具有相同功能的代码 sn-ps,但是一个可以编译,另一个不能编译。为什么?

这个编译。

vector<int>::iterator it;
if ((it=find(v.begin(),v.end(),2))!=v.end()){
}

这个没有。

if ((vector<int>::iterator it=find(v.begin(),v.end(),2))!=v.end()){
}

这是我得到的错误。

main.cpp: In function ‘int main()’:
main.cpp:32:28: error: expected primary-expression before ‘it’
main.cpp:32:28: error: expected ‘)’ before ‘it’
main.cpp:44:5: error: expected ‘)’ before ‘return’

附:可以随意编辑标题 - 我找不到任何描述性内容。

【问题讨论】:

  • 可以在if 语句中定义变量,但类型必须立即在第一个打开的括号之后(例如,if (int x = whatever))。代码中的第二个开放括号会破坏它(是的,这经常使该功能无用)。
  • 几年前我遇到了这个确切的问题,并在这里得到了很好的答案。 stackoverflow.com/questions/7836867/…

标签: c++ vector iterator


【解决方案1】:

如果() 的全部内容都以变量声明开头(即,如果它只是一个变量声明),您只能在if() 内定义一个变量。

您要做的是声明一个变量,然后对其进行测试。这是不允许的。

您可以退回到两行版本,也可以编写一个基于容器的find,使用boost::optionalstd::tr2::optional,如下所示:

namespace aux {
  using std::begin; using std::end;
  template<typename C> auto adl_begin( C&& c )->decltype( begin(std::forward<C>(c)) )
  { return begin(std::forward<C>(c)); }
  template<typename C> auto adl_end( C&& c )->decltype( end(std::forward<C>(c)) )
  { return end(std::forward<C>(c)); }
}
using aux::adl_begin; using aux::adl_end;

template<typename C, typename U>
optional< decltype( typename std::decay<*adl_begin( std::declval<C&>() )>::type ) >
my_find( C&& c, U&& u ) {
  auto it = std::find( adl_begin(c), adl_end(c), std::forward<U>(u) );
  if (it == adl_end(c))
    return {none_t};
  else
    return {it};
}

上面不是返回iterator,而是返回一个可选的iterator,在boolean 上下文中评估时,如果找不到该项目,则为false

您现在可以输入:

if( auto op_it = my_find( v, 2 ) ) {
  auto it = *op_it; // optional, but saves on `*` elsewhere
  // code
}

大致得到你想要的。

optionalboost 中可用,在std::tr2 中可用,在 C++14 中可能在std:: 中可用。 booststd 略有不同。

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多