tutorial smart remix online español curso aprender c++ gcc visual-c++ clang language-lawyer

c++ - smart - solidity español



Constructor eliminado: MSVC informa un error, Clang no lo hace (2)

Considera el siguiente código:

class SILPassPipelinePlan final { public: SILPassPipelinePlan() = default; ~SILPassPipelinePlan() = default; SILPassPipelinePlan(const SILPassPipelinePlan &) = default; SILPassPipelinePlan(SILPassPipelinePlan &&) = delete; SILPassPipelinePlan x() { SILPassPipelinePlan P; return P; } }; int main() { return 0; }

MSVC informa el siguiente error:

1> consoleapplication2.cpp (13): error C2280: ''SILPassPipelinePlan :: SILPassPipelinePlan (SILPassPipelinePlan &&)'': intentando hacer referencia a una función eliminada

1> consoleapplication2.cpp (8): nota: ver la declaración de ''SILPassPipelinePlan :: SILPassPipelinePlan''

Clang y GCC no.

Desde el punto de vista de la especificación, ¿qué compilador es el correcto? ¿Es esto un error de MSVC o un error de Clang?

MSVC es de la última actualización 3 de Visual Studio 2015, Clang es la versión 3.9.0.


C ++ 11 introdujo movimientos implícitos en ciertos escenarios, el tuyo incluido :

En los siguientes contextos de inicialización de copia, se puede usar una operación de movimiento en lugar de una operación de copia:

  • Si la expresión en una declaración return ([stmt.return]) es una expresión id (posiblemente entre paréntesis) que nombra un objeto con una duración de almacenamiento automática declarada en el cuerpo o parameter-declaration-clause de la función envolvente más interna o lambda-expression , o

  • [...]

la resolución de sobrecarga para seleccionar el constructor para la copia se realiza primero como si el objeto fuera designado por un valor r. Si la primera resolución de sobrecarga falla, [...]

Clang (la única implementación que acepta, por cierto) malinterpreta "falla" para incluir la selección de funciones eliminadas, o aplica [over.match.funcs] / 8 demasiado laxalmente. Ver error 31025 .


Todas las versiones de GCC en Wandbox rechazan este código. ¿Está probando esto por casualidad en una Mac y usando su Clang-masquerading-as-GCC?

Esto no tiene nada que ver con P0135. Clang simplemente está tomando una lectura excesivamente liberal de "falla" en lo que es actualmente [class.copy.elision] / 3 , que dice que en esta situación

la resolución de sobrecarga para seleccionar el constructor para la copia se realiza primero como si el objeto fuera designado por un valor r. Si la primera resolución de sobrecarga falla o no se realizó, [...] se vuelve a realizar la resolución de sobrecarga, considerando el objeto como un valor l.

Esa resolución de sobrecarga no falla; tiene éxito y selecciona el constructor de movimiento, que pasa a ser eliminado. Ese debería ser el final del asunto.

Esto ha sido reportado como error 31025 .