Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

272
Vistas
Ternary operator applied to different lambdas produces inconsistent results

Consider the following which uses the ternary operator to get the common function pointer type of the two lambdas

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

GCC-trunk only accepts it in C++14 but rejects it in C++17/20 with (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 accepts it in all C++14/17/20 mode (Demo).

MSVC-trunk only accepts it in C++20 but rejects it in C++14/17 with (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

Which compiler is right?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Since each lambda expression has a unique type, and neither lambda expression is convertible to the other, [expr.cond]/6 applies.

If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands ([over.match.oper], [over.built]). If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this subclause.

The candidates are ([over.built]/25):

For every type T, where T is a pointer, pointer-to-member, or scoped enumeration type, there exist candidate operator functions of the form

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

I believe that overload resolution should succeed in this case, and as a result, both operands should be converted to void(*)(int).

That is, IMO clang is correct.


Edit: I believe that [](auto) noexcept {} is convertible to void(*)(int), because it has a conversion function template template<class T> operator FP(), where FP is void(*)(T) ([expr.prim.lambda.closure]/9).

For a generic lambda with no lambda-capture, the closure type has a conversion function template to pointer to function. The conversion function template has the same invented template parameter list, and the pointer to function has the same parameter types, as the function call operator template. The return type of the pointer to function shall behave as if it were a decltype-specifier denoting the return type of the corresponding function call operator template specialization.

And I believe that template argument deduction should make this conversion template usable as a conversion to void(*)(int) ([temp.deduct.conv]/5).

Template argument deduction is done by comparing the return type of the conversion function template (call it P) with the type specified by the conversion-type-id of the conversion-function-id being looked up (call it A) as described in [temp.deduct.type].

[...]

In general, the deduction process attempts to find template argument values that will make the deduced A identical to A. However, certain attributes of A may be ignored:

  • [...]
  • If the original A is a function pointer or pointer-to-member-function type, its noexcept.
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda