Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

282
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!