AUTOSAR C++14 Rule A8-4-5

параметры «потреблять», объявленные как X & &, всегда должны быть перемещены из

Описание

Определение правила

параметры «потреблять», объявленные как X & &, всегда должны быть перемещены из.

Объяснение

При объявлении функции можно указать свое намерение переместить содержимое параметра функции, объявив его как неконституционную и неотключенную ссылку rvalue или «потреблять» (X&&) параметр. Например, параметр этой функции объявлен как параметр «потреблять»: void foo(std::vector<std::string>&& V). Это объявление подразумевает, что содержимое вектора V предназначен для перемещения вместо копирования в теле функции.

Когда вы объявляете параметр функции как параметр «потреблять», используйте семантику перемещения при использовании параметра. В теле функции используйте std::move функция явным образом, если вы используете ссылку lvalue для вызова функции.

Реализация Polyspace

Polyspace® помечает определение функции, если оба из этих условий верны:

  • По крайней мере, один функциональный параметр объявлен как неконст и нешаблон rvalue ссылки, то есть «потреблять» или X&& параметр.

  • Содержимое X&& параметр не полностью перемещается к другому объекту при помощи std::move функция в теле функции.

Polyspace не поднимает этот дефект в конструкторах перемещения и операторах назначения.

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

#include <utility>
class C
{
	C(C&& c): a{std::move(c.a)}     // Compliant by exception.
	{
	}

	C& operator=(C&& c)             // Compliant by exception.
	{
		a = std::move(c.a);

		return *this;
	}

	void move(C&& c)                // Noncompliant
	{
		a = std::move(c.a);//Partial move
	}

	void cond(C&& c, bool b)        // Compliant
	{
		if (b) {
			move(std::move(c));
		} else {
			a++;
		}
	}
public:
	int a;
	void set(int&& num)     // Compliant
	{
		a = std::move(num);
	}
	void set1(int&&)     // Noncompliant
	{
		//Unnamed temporary variable cannot be moved from.
	}
	void set2(int&& i12);  // Violation raised on definition.
	void set3(int&& i11a,  // Noncompliant
	int&& i11b)  // Noncompliant
	{
		if(i11a != i11b)
		{
		}
	}
	
};
void C::set2(int&& i12)   // Noncompliant
{
	a = i12;
}

template<typename T>
void tf1(T&& t1)      // Compliant - not a "consume" parameter
{
}

В этом примере представитель данных a класса C устанавливается в целое число при помощи семантики перемещения.

  • Polyspace не помечает конструктор перемещения и оператор назначения перемещения, хотя эти функции не полностью перемещают «потреблять» или X&& параметр. Эти функции совместимы с исключениями.

  • Polyspace помечает функцию C::move потому что тело функции частично перемещает «потреблять» или X&& параметр.

  • Polyspace помечает функцию C::set1 поскольку эта функция использует неназванный параметр «consume». Поскольку параметр не называется, вы не можете использовать функцию std::move на этом X&& параметр.

  • Polyspace помечает функцию C:: set2 потому что тело функции копирует параметр «consume» вместо использования функции std::move. Polyspace поднимает нарушение определения переменной. Точно так же функция C::set2 также не соответствует этому правилу, поскольку его тело не использует std::move на X&& переменные.

  • Функция C::cond и C::set соответствуют этому правилу, поскольку тела этих функций используют std::move по параметрам «потреблять».

  • Polyspace не помечает шаблон функции, поскольку это правило не применяется к шаблонам.

Проверяйте информацию

Группа: Деклараторы
Категория: Необходимый, Автоматизированный
Введенный в R2021a