Rozpoznawanie nazwy dla typów zależnych
Służy typename
do kwalifikowanych nazw w definicjach szablonów, aby poinformować kompilator, że dana kwalifikowana nazwa identyfikuje typ. Aby uzyskać więcej informacji, zobacz 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.
Wyszukiwanie nazw zależnych sprawdza nazwy z obu kontekstów definicji szablonu — w poniższym przykładzie ten kontekst znajdzie myFunction(char)
— i kontekst tworzenia wystąpienia szablonu. W poniższym przykładzie szablon jest tworzone jako wystąpienie główne; w związku z tym element MyNamespace::myFunction
jest widoczny od momentu utworzenia wystąpienia i jest wybierany jako lepsze dopasowanie. Jeśli MyNamespace::myFunction
nazwa została zmieniona, myFunction(char)
zostanie wywołana zamiast tego.
Wszystkie nazwy są rozpoznawane tak, jakby były nazwami zależni. Niemniej jednak zalecamy używanie w pełni kwalifikowanych nazw, jeśli występuje jakikolwiek możliwy konflikt.
// 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);
}
Dane wyjściowe
Int MyNamespace::myFunction
Uściślanie szablonu
Program Visual Studio 2012 wymusza standardowe reguły uściślania języka C++98/03/11 z słowem kluczowym "template". W poniższym przykładzie program Visual Studio 2010 będzie akceptować zarówno niekonformujące wiersze, jak i zgodne wiersze. Program Visual Studio 2012 akceptuje tylko zgodne wiersze.
#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;
}
Zgodność z regułami uściślania jest wymagana, ponieważ domyślnie język C++ zakłada, że AY::Rebind
nie jest to szablon, dlatego kompilator interpretuje następujące "<
" jako mniej niż. Musi wiedzieć, że Rebind
jest to szablon, aby mógł poprawnie przeanalizować "<
" jako nawias kątowy.
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla