Как создать вектор шаблонов?

0

Im пытается создать вектор шаблона типа, но продолжать получать ошибку

 template<class T>
 struct s{

    T val;

    public:
        s(T a)
        {
            val = a;
        };

        friend ostream& operator<<(ostream& os, const T& a);
 };

 template <typename T>
 ostream& operator<< (ostream& os, const T& a){
     return os << a.val;
 }

int main()
{
    s <double> names(4) ;
    s <int> figure(7);
    s <string> word();
    s <vector<int>*> arrays();
    cout << names << endl;
    cout << figure << endl;
    cout << arrays << endl;
    return 0;
}

Я продолжаю получать ту же ошибку -

request for member 'val' in 'a', which is of non-class type 's<std::vector<int>*>()'|

Любые советы будут высоко оценены

  • 0
    Для начала, ваша структура не имеет конструктора по умолчанию. И вы должны передать аргумент по константной ссылке.
  • 0
    Какие аргументы? те в инициализации типов данных?
Показать ещё 1 комментарий
Теги:
class
templates
vector

3 ответа

2
s <vector<int>*> arrays();

Это не создает экземпляр объекта, он объявляет функцию, которая возвращает s<vector<int>*>, и, как следствие:

cout << arrays << endl;

Пытается распечатать указатель на функцию, создав экземпляр вашего шаблонного operator<<:

template <typename T>
ostream& operator<< (ostream& os, const T& a){
    return os << a.val;
}

с:

T = s<vector<int>*>(*)();

и поэтому указатель на функцию a не имеет поля .val которое вызывает ошибку.

  • 0
    ОК, поэтому я удалил скобки после массивов. Следовательно, теперь это будет вектор <int> типа s, если я не ошибаюсь? И если бы я хотел реализовать функцию get (), которая бы возвращала val, как бы я поступил так? Спасибо за помощь, ребята, все прояснилось
  • 0
    @ user3504476: T& get() { return val; } const T& get() const { return val; } , а если быть точным, теперь у вас есть T = std::vector<int>* , поэтому val - указатель на вектор целых
Показать ещё 6 комментариев
2
s <vector<int>*> arrays();

Объявляет функцию с именем arrays, не принимает аргументов и возвращает s<vector<int>*>. Удалите лишние круглые скобки или замените их на {} для С++ 11. Конечно, ваш s не поддерживает конструкцию по умолчанию, поэтому вам нужно дать ему конструктор по умолчанию - это может быть так же просто, как дать конструктору аргумент по умолчанию:

    s(T a = T())
    {
        val = a;
    }

и лучше использовать список инициализации членов вместо назначения и принять const ref вместо значения, поскольку T может быть большим:

    s(const T& a = T()) : val(a) { }

В С++ 11 вы должны взять по значению и переместить a в val вместо:

     s(T a = T()) : val(std::move(a)) { }

Также,

 template <typename T>
 ostream& operator<< (ostream& os, const T& a){
     return os << a.val;
 }

будет соответствовать всему, что под солнцем. Лучше всего соответствовать только s:

 template <typename T>
 ostream& operator<< (ostream& os, const s<T>& a){
     return os << a.val;
 }

В заключение,

friend ostream& operator<<(ostream& os, const T& a);

подружится (и объявит) простую функцию, а не шаблон функции. Чтобы подружиться с operator << шаблона operator << как было изменено выше:

    template <typename U>
    friend ostream& operator<<(ostream& os, const s<U>& a);

Или даже лучше, удалите оператор шаблона и определите функцию friend inline (внутри определения класса):

    friend ostream& operator<<(ostream& os, const s<T>& a){
        return os << a.val;
    }

Это более компактно, а также ограничивает дружбу подходящей версией operator <<, а не все экземпляры шаблона.

Демо.

1

Вся проблема в том, что это

ClassName InstanceName();

не создает экземпляр ClassName с использованием конструктора по умолчанию, но объявляет функцию. Чтобы делать то, что вы хотели (и я полагаю, что это создание экземпляров со стандартными конструкторами), используйте синтаксис

ClassName InstanceName;

Итак, чтобы исправить ваши ошибки, измените

s <string> word();
s <vector<int>*> arrays();

в

s <string> word;
s <vector<int>*> arrays;

и добавьте конструктор по s умолчанию для вашего класса s.

  • 0
    Хорошо, я сделал это сейчас. Кажется, что созданный мной вектор не имеет возможности push_back? Должен ли я назначить его размер или что?
  • 0
    Причина этого полностью зависит от вашей реализации.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню