在`if constexpr`块内声明的变量范围

时间:2017-10-23 00:49:55

标签: c++ scope c++17 constexpr

这是不正确的还是仅仅是编译器(在我的情况下是g ++ - 7)仍然是错误的?因为它说n没有定义。

template<class T>
auto tup(T const& t)
{
    if constexpr(hana::length(t)() % 2)
        auto n = hana::append(t, nullptr);
    else
        auto const& n = t;

    return n;
}

int main()
{
   std::cout << hana::length(tup(std::tuple(3, "h", 'c'))) << '\n';
}

n将始终定义,无论编译器将进入哪个分支。

2 个答案:

答案 0 :(得分:5)

您的程序格式错误,因为每个n仅限于声明它的单个语句的范围。

C ++ 17草案N4659 [stmt.select] / 1说:

  

selection-statement 中的子语句(每个子语句,else语句的if形式)隐式定义块范围([basic.scope]) 。如果selection-statement中的子语句是单个语句而不是 compound-statement ,则就好像它被重写为包含原始子语句的复合语句一样。 [示例:

if (x)
  int i;
  

可以等效地重写为

if (x) {
  int i;
}
  

因此,在if语句后,i不再在范围内。 - 结束示例]

此规则适用于所有forwhileswitchif语句 - constexpr关键字是否与{{1}一起使用}}

答案 1 :(得分:2)

在这种情况下,

constexpr不会改变任何内容。

这与此示例完全相同

int foo (int a)
 {
   if ( a == 0 )
    {
      int r = 0;
    }
   else
    {
      int r = 0;
    }

   return r;
 }
两种情况都定义了

r。具有相同的价值。

r的范围仅限于if,且未达到return

如果你可以解决立即返回的问题;我的意思是

template<class T>
auto tup(T const& t)
{
    if constexpr(hana::length(t)() % 2)
        return hana::append(t, nullptr);
    else
        return t;
}