相关类型的名称转换
为限定名使用 typename 在模板定义通知编译器该命名的限定名标识一个类型。 有关更多信息,请参见 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.");
}
Output
Name resolved by using typename keyword.
依赖的名称查找检查从两个的名称模板的上下文定义在下面的示例中,此上下文中查找 myFunction(char)—和模板实例化的上下文。 在下面的示例中,模板在主实例化;因此,MyNamespace::myFunction 从问题可见实例化并已选择作为更好的匹配。 如果重命名 MyNamespace::myFunction,将调用 myFunction(char)。
所有名称都得到解决,就好像它们是依赖名称。 但是,建议您使用完全限定名,如果有任何可能的冲突。
//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);
}
Output
Int MyNamespace::myFunction
模板。
Visual Studio 2012 中的 Visual C++ 执行区分的C++98/03/11标准规则与“模板”关键字。 在下面的示例中,Visual C++ 2010 将接受非兼容的行和匹配的行。Visual Studio 2012 中的 Visual C++ 只接受匹配的行。
#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;
}
需要使用消除规则的一致性,这是因为,默认情况下,C++,假设 AY::Rebind 不是模板,并且,因此编译器解释下面的“<”为小于。它必须知道 Rebind 是模板,以便可以正确分析“<”作为尖括号。