Rozlišení názvů u závislých typů
Slouží typename
k kvalifikovaným názvům v definicích šablony, aby kompilátoru řekl, že daný kvalifikovaný název identifikuje typ. Další informace najdete v tématu 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.
Vyhledávání názvů závislých názvů zkoumá názvy z kontextu definice šablony – v následujícím příkladu by tento kontext našel myFunction(char)
– a kontext instance šablony. V následujícím příkladu se šablona vytvoří instance v main; proto MyNamespace::myFunction
je viditelný z bodu vytvoření instance a je vybrán jako lepší shoda. Pokud by byla funkce MyNamespace::myFunction
přejmenována, došlo by k zavolání funkce myFunction(char)
.
Všechny názvy jsou vyhodnoceny jako závislé názvy. Přesto je doporučeno používat plně kvalifikované názvy, může-li dojít k jakýmkoli konfliktům.
// 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);
}
Výstup
Int MyNamespace::myFunction
Odstraňování mnohoznačnosti šablon
Visual Studio 2012 vynucuje standardní pravidla C++98/03/11 pro nejednoznačnost pomocí klíčového slova šablona. V následujícím příkladu by Sada Visual Studio 2010 přijímala nekonformující řádky i odpovídající řádky. Visual Studio 2012 přijímá pouze odpovídající řádky.
#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;
}
Shoda s pravidly odstraňování mnohoznačnosti je požadována, protože jazyk C++ standardně předpokládá, že typ AY::Rebind
není šablona, proto kompilátor interpretuje následující znak „<
“ jako znak „menší než“. Pro správnou analýzu znaku „Rebind
“ jako ostré závorky musí kompilátor vědět, že typ <
je šablona.
Viz také
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro