una retornar resta multiplicar metodos los listas lista elementos elemento como cada arreglos agregar c++ templates tuples c++11 argument-dependent-lookup

c++ - retornar - multiplicar elementos de una lista



obteniendo un elemento de una tupla (2)

ADL no se aplica directamente a los identificadores de plantilla , como get<0> , por lo que el compilador realmente no se inicia en esa ruta. C ++ 11 §14.8.1 / 8 (en C ++ 03, 14.8.1 / 6):

[Nota: para nombres de funciones simples, la búsqueda dependiente del argumento (3.4.2) se aplica incluso cuando el nombre de la función no es visible dentro del alcance de la llamada. Esto se debe a que la llamada todavía tiene la forma sintáctica de una llamada de función (3.4.1). Pero cuando se usa una plantilla de función con argumentos de plantilla explícitos, la llamada no tiene la forma sintáctica correcta a menos que haya una plantilla de función con ese nombre visible en el punto de la llamada. Si no se ve tal nombre, la llamada no está sintácticamente bien formada y no se aplica la búsqueda dependiente del argumento. Si algún nombre de este tipo es visible, se aplica una búsqueda dependiente del argumento y se pueden encontrar plantillas de funciones adicionales en otros espacios de nombres.

Se va a dar un breve ejemplo. Así que la solución es bastante fácil:

#include <tuple> template< typename > // BEGIN STUPID BUT HARMLESS HACK void get( struct not_used_for_anything ); // END STUPIDITY auto t = std::make_tuple(false, false, true); bool a = get<0>(t); // Now the compiler knows to use ADL! bool b = std::get<0>(t); // okay

http://ideone.com/fb8Ai

Tenga en cuenta que not_used_for_anything en lo anterior es simplemente un mecanismo de seguridad. Se pretende que sea un tipo incompleto que nunca se completa. Omitirlo también funciona, pero no es seguro porque podría chocar con una firma que podría desear.

template< typename > void get() = delete;

http://ideone.com/WwF2y

Nota: la cita anterior de la Norma no es normativa, lo que significa que, en opinión del Comité, podríamos resolver esto sin explicación, porque está implícito en el resto del idioma y la gramática, en particular el hecho de que 3.4 .2 no dice nada sobre buscar ids de plantillas. ¡Sí claro!

Posible duplicado:
¿Por qué ADL no encuentra plantillas de funciones?

La llamada a get no parece invocar la búsqueda dependiente del argumento:

auto t = std::make_tuple(false, false, true); bool a = get<0>(t); // error bool b = std::get<0>(t); // okay

g ++ 4.6.0 dice:

error: ''get'' was not declared in this scope

Visual Studio 2010 dice:

error C2065: ''get'': undeclared identifier

¿Por qué?


Se debe a que intenta crear una instancia explícita de la plantilla de función get , proporcionando 0 como argumento de plantilla. En el caso de las plantillas, ADL funciona si una plantilla de función con ese nombre es visible en el punto de la llamada. Esta plantilla de función visible solo ayuda a desencadenar ADL (puede que no se use en realidad ) y luego, se puede encontrar una mejor coincidencia en otros espacios de nombres.

Tenga en cuenta que la plantilla de función que activa (o habilita) ADL, no necesita tener una definición :

namespace M { struct S{}; template<int N, typename T> void get(T) {} } namespace N { template<typename T> void get(T); //no need to provide definition // as far as enabling ADL is concerned! } void f(M::S s) { get<0>(s); //doesn''t work - name `get` is not visible here } void g(M::S s) { using N::get; //enable ADL get<0>(s); //calls M::get }

En g() , el nombre N::get desencadena ADL al llamar a get<0>(s) .

Demostración: http://ideone.com/83WOW

C ++ (2003) sección 14.8.1 / 6 lecturas,

[Nota: para nombres de funciones simples, la búsqueda dependiente del argumento (3.4.2) se aplica incluso cuando el nombre de la función no es visible dentro del alcance de la llamada. Esto se debe a que la llamada todavía tiene la forma sintáctica de una llamada de función (3.4.1). Pero cuando se usa una plantilla de función con argumentos de plantilla explícitos, la llamada no tiene la forma sintáctica correcta a menos que haya una plantilla de función con ese nombre visible en el punto de la llamada. Si no se ve tal nombre, la llamada no está sintácticamente bien formada y no se aplica la búsqueda dependiente del argumento. Si algún nombre de este tipo es visible, se aplica una búsqueda dependiente del argumento y se pueden encontrar plantillas de funciones adicionales en otros espacios de nombres.

[Ejemplo:

namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); //ill-formed: not a function call A::f<3>(b); //well-formed C::f<3>(b); //ill-formed; argument dependent lookup // applies only to unqualified names using C::f; f<3>(b); //well-formed because C::f is visible; then // A::f is found by argument dependent lookup }

—En el ejemplo] —en la nota final]