依赖类型的名称解析
使用 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.");
}
Name resolved by using typename keyword.
针对依赖名称的名称查找将检查模板定义上下文(在下面的示例中,此上下文将查找 myFunction(char)
)和模板实例化上下文中的名称。在下面的示例中,将在 main 中实例化模板;因此,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);
}
输出
Int MyNamespace::myFunction
模板消除歧义
Visual Studio 2012 强制实施 C++98/03/11 标准规则以使用“template”关键字消除歧义。 在下面的示例中,Visual Studio 2010 将接受不一致性行和一致性行。 Visual Studio 2012 仅接受一致性行。
#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
是模板,这样才能正确地将“<
”分析为尖括号。
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈