Compartir a través de


Resolución de nombres para los tipos de Dependientes

Utilice typename para los nombres completos en definiciones de plantilla para indicar al compilador que el nombre completo dado identifica un tipo.Para obtener más información, vea typename.

// template_name_resolution1.cpp
#include <stdio.h>
template <class T> class X
{
public:
   void f(typename T::myType* mt) {}
};

class Yarg
{
public:
   struct myType { };
};

int main()
{
   X<Yarg> x;
   x.f(new Yarg::myType());
   printf("Name resolved by using typename keyword.");
}

dx2zs2ee.collapse_all(es-es,VS.110).gifOutput

Name resolved by using typename keyword.

La búsqueda de nombre para los nombres dependientes examina nombres del contexto de la plantilla definición- en el ejemplo siguiente, este contexto produce myFunction(char))y el contexto de la instancia de la plantilla.En el ejemplo siguiente, la plantilla se crea instancias en main; por consiguiente, MyNamespace::myFunction es visible del punto de la instancia y se elige como la mejor coincidencia.Si MyNamespace::myFunction fuera cambiado, myFunction(char) se denominaría en su lugar.

Se resuelven todos los nombres como si fueran nombres dependientes.Sin embargo, recomendamos utilizar nombres completos si hay algún conflicto posible.

//template_name_resolution2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

void myFunction(char)
{
   cout << "Char myFunction" << endl;
}

template <class T> class Class1
{
public:
   Class1(T i)
   {
      // If replaced with myFunction(1), myFunction(char)
      // will be called
      myFunction(i);
}
};

namespace MyNamespace
{
   void myFunction(int)
   {
      cout << "Int MyNamespace::myFunction" << endl;
   }
};

using namespace MyNamespace;

int main()
{
   Class1<int>* c1 = new Class1<int>(100);
}

dx2zs2ee.collapse_all(es-es,VS.110).gifOutput

Int MyNamespace::myFunction

dx2zs2ee.collapse_all(es-es,VS.110).gifDesambiguación de plantilla

Visual C++ en Visual Studio 2012 aplica las reglas estándar C++98/03/11 para la desambiguación con la palabra clave “plantilla”.En el ejemplo siguiente, Visual C++ 2010 aceptaba las líneas no conformes y líneas que cumplen. Visual C++ en Visual Studio 2012 sólo acepta las líneas que cumplen.

#include <iostream>
#include <ostream>
#include <typeinfo>
using namespace std;

template <typename T> struct Allocator {
    template <typename U> struct Rebind {
        typedef Allocator<U> Other;
    };
};

template <typename X, typename AY> struct Container {
    #if defined(NONCONFORMANT)
        typedef typename AY::Rebind<X>::Other AX; // nonconformant
    #elif defined(CONFORMANT)
        typedef typename AY::template Rebind<X>::Other AX; // conformant
    #else
        #error Define NONCONFORMANT or CONFORMANT.
    #endif
};

int main() {
    cout << typeid(Container<int, Allocator<float>>::AX).name() << endl;
}

Compatibilidad con las reglas de la desambiguación se requiere porque, de forma predeterminada, C++ supone que AY::Rebind no es una plantilla, por lo que el compilador interpreta “<siguiente” como menos- que. Debe saber que Rebind es una plantilla para que pueda analizar correctamente “<” como corchete angular.

Vea también

Referencia

Plantillas y resolución de nombres