使用{}报告未使用的变量进行统一初始化

Uniform initialization with {} reporting unused variable

本文关键字:初始化 变量 报告 未使用 使用      更新时间:2023-10-16

使用g++4.7.0(-Wall -Wextra -Werror -Wconversion -std=c++11)编译此代码:

#include <iostream>  // std::cout, std::endl
#include <string>    // std::string
#include <utility>   // std::move
void out(std::string const &message)
{
   static int count{0};
   std::cout << count++ << " = " << message << std::endl;
}
struct Foo
{
   Foo()                         {out("constructor");}
  ~Foo()                         {out("destructor");}
   Foo(Foo const &)              {out("copy constructor");}
   Foo & operator=(Foo const &)  {out("copy via assignment"); return *this;}
   Foo(Foo &&)                   {out("move constructor");}
   Foo & operator=(Foo &&)       {out("move via assignment"); return *this;}
};
int main()
{
   auto bar{std::move(Foo())};
   out("exiting main");
}

导致以下错误:

error: unused variable 'bar' [-Werror=unused-variable]

我可以通过将bar初始化更改为以下任一项来消除错误:

/* 0 */ auto bar(std::move(Foo()));
/* 1 */ Foo bar{std::move(Foo())};
/* 2 */ Foo bar(std::move(Foo()));
/* 3 */ auto bar = std::move(Foo());
/* 4 */ Foo bar = std::move(Foo());
/* 5 */ auto bar __attribute__((unused)) {std::move(Foo())};

一旦更改了bar初始化,输出总是

0 = constructor
1 = move constructor
2 = destructor
3 = exiting main
4 = destructor

为什么原始bar初始化报告一个未使用的变量?

auto bar{std::move(Foo())};

在此声明之后,bar的类型为std::initializer_list<Foo>,它具有琐碎的复制/移动操作和析构函数。您的其他申报

auto bar(std::move(Foo()));
Foo bar{std::move(Foo())};
Foo bar(std::move(Foo()));
auto bar = std::move(Foo());
Foo bar = std::move(Foo());

bar声明为FooFoo&&,这会抑制警告,因为它具有非平凡的特殊成员函数。

除非您特别打算创建std::inializer_list对象,否则通常不希望使用auto进行支持初始化。

嗯,bar未使用。您可能想要为编译器提交一个缺陷,因为在其他情况下,这似乎是错误地未被检测到的。