Propagacja "typedef" z klasy bazowej na pochodną dla "szablonu"
Próbuję zdefiniować klasę bazową, która zawiera tylko typedef.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
Dlaczego w B dostaję błąd, że Vec_t nie jest rozpoznawany i muszę go wyraźnie napisać?
typename A<T>::Vec_t v;
7 answers
Uważam, że to pytanie jest zduplikowane, ale nie mogę go teraz znaleźć. Standard C++ mówi, że należy w pełni zakwalifikować nazwę zgodnie z 14.6.2/3:
W definicji szablonu klasy lub elementu szablonu klasy, jeśli klasa bazowa szablonu klasy zależy od parametru szablonu, zakres klasy bazowej nie jest sprawdzany podczas wyszukiwania bez zastrzeżeń nazwy ani w punkcie definicji szablonu klasy lub elementu, ani podczas tworzenia instancji klasy szablon lub członek.
UPD: I found duplicate finally: here it is.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:57
Istnieje coś, co nazywa się zależnymi i nie zależnymi nazwami w przypadku szablonów.
Jeśli nazwa zależy od parametru szablonu t to zależne nazwa i inne, które nie zależą od parametru T są niezależne nazwy.
Oto zasada: kompilator nie szukać w zależnych klasach bazowych (jak A) patrząc w górę nazwy (np. Vec_t). W rezultacie, kompilator nie wie, że nawet istnieć nie mówiąc już o tym, że są typy.
Kompilator nie może zakładać, że Vec_t
jest typem, dopóki nie zna T
, ponieważ istnieje potencjalna specjalizacja A<T>
Gdzie A<T>:: Vec_t
jest członkiem danych
Więc rozwiązaniem jest użycie typename
typename A<T>::Vec_t v; ← good
Polecam Ci przejść przez to https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types .
Stary (uszkodzony) link: http://www.parashift.com/c++ - faq-lite / templates.html#faq-35.18
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 13:53:56
Ponieważ kompilator nie jest pewien, że Vec_t
nazywa Typ. Na przykład, A<T>
może być wyspecjalizowane dla T=int
do , a nie mieć ten konkretny typedef
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 11:38:38
Dla kompletności, oto jak możesz złagodzić ten uciążliwość trochę, albo:
- przepisać te typy w klasach pochodnych, lub lepiej - jak z metody -
- po prostu zaimportuj te nazwy w klasie pochodnej z
using declaration
:
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
public:
using typename A<T>::Vec_t;
// .........
private:
Vec_t v;
};
Może być przydatne, jeśli masz więcej niż jedną wzmiankę o dziedziczonej typedef
w klasie pochodnej. Nie musisz też dodawać typename
za każdym razem z tym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-06 16:34:50
Musisz jednoznacznie zakwalifikować użycie Vec_t
, ponieważ kompilator nie wie, skąd pochodzi Vec_t
.
Nie może zakładać niczego o strukturze A, ponieważ szablon klasy A może być wyspecjalizowany. Specjalizacja może zawierać Vec_t
, który nie jest typedef, lub może nawet nie zawierać członka Vec_t
w ogóle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 11:40:21
Vec_t nie jest nazwą zależną, a kompilator musi wiedzieć co to jest bez tworzenia instancji szablonów (w tym przypadku klasa bazowa). Naprawdę nie różni się od:
template <class T>
class X
{
std::string s;
}
Tutaj również kompilator musi wiedzieć o std:: string, nawet jeśli X nie jest instancją, ponieważ nazwa nie zależy od argumentu szablonu T (O ile kompilator może zakładać).
Podsumowując, typedefs w klasie bazowej szablonu wydają się raczej bezużyteczne do użycia w klasie pochodnej. Do rodzaju należą następujące gatunki przydatne jednak dla użytkownika.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 11:44:13
Pojęcie to może być związane ze sposobem, w jaki używamy std::vector<T>
. Na przykład, jeśli mamy std::vector<int> Foo
. Teraz zdecydujemy się użyć dowolnego z jego typów, powiedzmy iterator
. W tym scenariuszu wyraźnie wspominamy
std::vector<int>::iterator foo_iterator;
Podobnie w Twoim przypadku, aby użyć typu public member Vec_t
z template <typename T> class A
, musisz jawnie zadeklarować go jako
A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 17:01:59