Как использовать шаблоны для создания псевдонимов с помощью "using" (создание параметризованных псевдонимов) в C++?

в настоящее время я читаю "язык программирования C++" 4-го издания Бьярне Страуструпа. В первых частях книги я нашел использование using выглядит следующим образом:

// Error is in these 2 lines
template<typename T>
using Iterator<T> = typename T::iterator;

* см. [ * * ] для полной программы и сообщения об ошибке*

это именно то, что я нашел на странице 105. Когда я превратил это в полную программу и попытался ее скомпилировать, g++ дал мне эту ошибку masseage:

> g++ -std=c++14 -o fnd find_all.cpp
find_all.cpp:13:15: error: expected '=' before '<' token
 using Iterator<T> = typename T::iterator;
           ^
find_all.cpp:13:15: error: expected type-specifier before '<' token

Я не могу найти проблема в этом коде (я новичок в C++, я не могу найти проблему с моими маленькими знаниями)( более смущающе я нашел это в книге Бьярне )

может кто-нибудь сказать мне, почему этот код дает ошибку?

Примечание: однако, если я заменить Iterator<C> С typename C::iterator (см. ниже), он отлично работает, ошибки нет!

[**]полная программа и сообщение об ошибке:

// Error is in these 2 lines
template<typename T>
using Iterator<T> = typename T::iterator;
// -------------------------------------------

// For the completeness I'll include my complete program here
template<typename C, typename V>
vector<Iterator<C>> find_all(C& c, V v) // find all occurrences of v in c
{
    vector<Iterator<C>> res;
    for (auto p = c.begin(); p!=c.end(); ++p)
        if (∗p==v)
            res.push_back(p);
    return res;
}

void test()
{
    string m {"Mary had a little lamb"};
    for (auto p : find_all(m, 'a'))
        if (*p == 'a')
            cerr << "string bug!n";

    list<double> ld { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 1.1, 1.1 };
    for (auto p : find_all(ld, 1.1))
        if (*p == 1.1)
            cerr << "list bug!n";

    vector<string> strv { "blue", "yellow", "red", "white", "orange", "blue" };
    for (auto p : find_all(strv, "blue"))
        if (*p == "blue")
            cerr << "string vector bug!n";

}

int main(void) 
{
    test();

    return 0;
}

СООБЩЕНИЕ ОБ ОШИБКЕ:

> g++ -std=c++14 -o fnd find_all.cpp
find_all.cpp:13:15: error: expected '=' before '<' token
 using Iterator<T> = typename T::iterator;
           ^
find_all.cpp:13:15: error: expected type-specifier before '<' token
find_all.cpp:16:8: error: 'Iterator' was not declared in this scope
 vector<Iterator<C>> find_all(C& c, V v)
    ^
find_all.cpp:16:17: error: template argument 1 is invalid
 vector<Iterator<C>> find_all(C& c, V v)
             ^
find_all.cpp:16:17: error: template argument 2 is invalid
find_all.cpp:16:18: error: expected unqualified-id before '>' token
 vector<Iterator<C>> find_all(C& c, V v)
              ^
find_all.cpp: In function 'void test()':
find_all.cpp:30:31: error: 'find_all' was not declared in this scope
  for (auto p : find_all(m, 'a'))
                           ^
find_all.cpp:35:32: error: 'find_all' was not declared in this scope
  for (auto p : find_all(ld, 1.1))
                            ^
find_all.cpp:40:37: error: 'find_all' was not declared in this scope
  for (auto p : find_all(strv, "blue"))

2 ответов


первый <T> должно быть опущено

template<typename T>
using Iterator = typename T::iterator;

при определении шаблона класса или шаблона функции, можно использовать:

template <typename T> struct Foo { };

template <typename T> T bar() { return T{}; }

вы не используете Foo<T> или bar<T> при определении шаблонов.

аналогично, при использовании шаблонов для определения псевдонима необходимо использовать:

template <typename T>
using Iterator = typename T::iterator;
             ^^ Don't include <T>