exponenta event banner

Правило AUTOSAR C++ 14 A8-4-5

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

Описание

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

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

Объяснение

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

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

Внедрение Polyspace

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

  • По крайней мере, один параметр функции объявляется как ссылка rvalue, отличная от const и non template, то есть «потребляйте» или 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 поскольку эта функция использует неназванный параметр «потребляй». Поскольку параметр не имеет имени, нельзя использовать функцию std::move на этом X&& параметр.

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

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

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

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

Группа: Деклараторы
Категория: Обязательно, Автоматизировано
Представлен в R2021a