Положение / Порядок конструктора перемещения в классе имеет значение? Шаблонный оператор приведения вместе с конструктором перемещения

Это похоже на ошибку компилятора, но дело настолько простое, что я немного скептически отношусь, поэтому я ищу подтверждение. Воспроизводится с VS2010 и VS2012.
Приведенный ниже пример не компилируется. Эта ошибка дана:

Ошибка 1 ошибка C2440: «приведение типа»: невозможно преобразовать из
‘ConvertibleToAny’ в ‘OtherType<_Ty> ‘test.cpp 40

Если вы переместите позицию конструктора перемещения OtherType(ThisType &&) над конструктором OtherType( int )Вдруг компилируется.

#include "stdafx.h"#include <string>

using namespace std;

template<class _Ty>
struct OtherType
{
typedef OtherType<_Ty>  ThisType;

OtherType()
{
}

OtherType( int )
{
}

// The move constructor
OtherType(ThisType && )
{
}
};

struct ConvertibleToAny
{
template <class AnyType>
operator AnyType()
{
return AnyType();
}
};

int _tmain(int argc, _TCHAR* argv[])
{

(OtherType<wstring>) ConvertibleToAny();

return 0;
}

Это ошибка или это ожидаемое поведение? Если ожидается, пожалуйста, процитируйте соответствующий абзац из спецификации C ++ 11.
Я уже опубликовал это как ошибку в Microsoft Connect, нажмите здесь, чтобы открыть его.

3

Решение

Ваше выражение

(OtherType<wstring>) ConvertibleToAny()

является унарным явным приведением (5.4) из временного пользовательского типа к пользовательскому типу, интерпретируемому в 5.4: 4 как static_cast:

static_cast<OtherType<wstring>>(ConvertibleToAny())

который согласно 5.2.9: 4 имеет смысл инициализации временной переменной t:

OtherType<wstring> t(ConvertibleToAny())

Это прямая инициализация (8.5: 15) и как таковые (8.5: 16) все конструкторы с одним аргументом OtherType участвовать в разрешении перегрузки согласно правилам 13.3.1.3.

После 13.3: 2 оба int и конструкторы перемещения доступны и являются жизнеспособными согласно 13.3.2, поэтому у нас есть две возможные последовательности неявного преобразования (13.3.3.1) для одного аргумента:

ConvertibleToAny [temporary] -> int
ConvertibleToAny [temporary] -> OtherType<wstring> &&

Следуя 13.3.3.1.2, между этими последовательностями нет упорядочения, поэтому не существует наилучшей жизнеспособной функции, происходит сбой разрешения перегрузки (13.3: 3), и программа имеет неправильную форму.


Если выполнена функция преобразования (12.3.2) explicit (12.3.2: 2), тогда он рассматривается только для прямой инициализации. Хотя последовательности неявного преобразования (13.3.3.1) являются неявными преобразованиями (4: 3) и, таким образом, включают инициализацию копирования, цель стандарта в примере 12.3.2: 2 состоит в том, что в этом случае следует учитывать функции явного преобразования. ; как таковой, снова кажется, что разрешение перегрузки должно потерпеть неудачу.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]