Единая инициализация с {} сообщением о неиспользованной переменной - PullRequest
6 голосов
/ 18 марта 2012

Компиляция этого кода с помощью 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 инициализация сообщает о неиспользованной переменной?

Ответы [ 2 ]

8 голосов
/ 18 марта 2012
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 как Foo или Foo&&, что подавляет предупреждение, поскольку оно имеет нетривиальные специальные функции-члены.

Как правило, вам не требуется инициализация в скобках с помощью auto, если вы специально не собираетесь создавать объект std::inializer_list.

2 голосов
/ 18 марта 2012

Ну, bar не используется. Возможно, вы захотите зарегистрировать дефект для компилятора, так как в других ситуациях он, похоже, по ошибке не обнаруживается.

...