Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

276
Visualizações
El operador ternario aplicado a diferentes lambdas produce resultados inconsistentes

Considere lo siguiente que usa el operador ternario para obtener el tipo de puntero de función común de las dos lambdas

 int main() { true ? [](auto) noexcept {} : [](int) {}; }

GCC-trunk solo lo acepta en C++14 pero lo rechaza en C++17/20 con ( Demo ):

 <source>:2:8: error: operands to '?:' have different types 'main()::<lambda(auto:1)>' and 'main()::<lambda(int)>' 2 | true ? [](auto) noexcept {} : [](int) {}; | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Clang-trunk lo acepta en todos los modos C++14/17/20 ( Demo ).

MSVC-trunk solo lo acepta en C++20 pero lo rechaza en C++14/17 con ( Demo ):

 <source>(2): error C2446: ':': no conversion from 'main::<lambda_01e5bb79b5a210014fb78333f6af80f9>' to 'main::<lambda_57cf6f5767bc1bee4c1e1d9859a585d2>' <source>(2): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

¿Qué compilador es el correcto?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Dado que cada expresión lambda tiene un tipo único y ninguna expresión lambda se puede convertir en otra, se aplica [expr.cond]/6 .

Si el segundo y el tercer operando no tienen el mismo tipo, y cualquiera tiene un tipo de clase (posiblemente cv calificado), la resolución de sobrecarga se usa para determinar las conversiones (si las hay) que se aplicarán a los operandos ([over.match.oper ], [sobreconstruido]). Si la resolución de sobrecarga falla, el programa está mal formado. De lo contrario, se aplican las conversiones así determinadas y los operandos convertidos se usan en lugar de los operandos originales para el resto de esta subcláusula.

Los candidatos son ( [over.built]/25 ):

Para cada tipo T , donde T es un puntero, puntero a miembro o tipo de enumeración con ámbito, existen funciones de operador candidatas de la forma

 T operator?:(bool, T, T);

Creo que la resolución de sobrecarga debería tener éxito en este caso y, como resultado, ambos operandos deberían convertirse en void(*)(int) .

Es decir, IMO clang es correcto.


Editar: creo que [](auto) noexcept {} es convertible a void(*)(int) , porque tiene una plantilla de función de conversión template<class T> operator FP() , donde FP es void(*)(T) ( [expr.prim.lambda.cierre]/9 ).

Para una lambda genérica sin captura de lambda, el tipo de cierre tiene una plantilla de función de conversión para apuntar a la función. La plantilla de función de conversión tiene la misma lista de parámetros de plantilla inventada, y el puntero a función tiene los mismos tipos de parámetros que la plantilla de operador de llamada de función. El tipo de retorno del puntero a la función se comportará como si fuera un especificador de tipo de declinación que denota el tipo de retorno de la especialización de plantilla de operador de llamada de función correspondiente.

Y creo que la deducción del argumento de la plantilla debería hacer que esta plantilla de conversión se pueda utilizar como una conversión a void(*)(int) ( [temp.deduct.conv]/5 ).

La deducción del argumento de la plantilla se realiza comparando el tipo de retorno de la plantilla de la función de conversión (llámela P ) con el tipo especificado por el id del tipo de conversión de la id de la función de conversión que se busca (llámela A ) como se describe en [ temp.deduct.type].

[...]

En general, el proceso de deducción intenta encontrar valores de argumentos de plantilla que hagan que la A deducida sea idéntica a A . Sin embargo, ciertos atributos de A pueden ignorarse:

  • [...]
  • Si el A original es un puntero de función o un tipo de función de puntero a miembro, es noexcept .
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda