Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/56: Рейтинг темы: голосов - 56, средняя оценка - 4.50
1405 / 647 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
1

Шаблоны. Ошибка компиляции: "Не удается сопоставить определение функции существующему объявлению"

01.09.2014, 00:31. Показов 10448. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
vector.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#pragma once
#ifndef _VECTOR_H
#define _VECTOR_H
 
 
#include <exception>
 
 
template<typename T> class vector {
    public:
        vector(unsigned int = 0, const T& = T());
        template<typename InputIterator> vector(InputIterator, InputIterator);
        vector(const vector<T>&);
        vector& operator=(const vector<T>&);
        ~vector();
        void reserve(unsigned int n);
        void push_back(const T&);
        unsigned int capacity() const { return _capacity; }
        unsigned int size() const { return _size; }
        T& at(unsigned int n);
        void clear();
        T& back();
        void assign(unsigned int n, const T& = T());
        template<typename InputIterator> void assign(InputIterator, InputIterator);
        T& operator[](unsigned int n) { return _elem[n]; }
    private:
        T* _elem;
        unsigned int _size, _capacity;
};
 
 
#endif //_VECTOR_H
vector.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "vector.h"
 
 
template <typename T> vector<T>::vector(unsigned int n, const T& val)
{
    assign(n, val);
}
 
 
template <typename T, typename InputIterator> vector<T>::vector(InputIterator _first, InputIterator _last)
{
    assign(_first, _last);
}
 
 
template <typename T> vector<T>::vector(const vector<T>& v)
{
    reserve(v._size);
    for(int i=0; i<_size; ++i)
        _elem[i] = v._elem[i];
}
 
 
template <typename T> vector<T>::~vector()
{
    delete[] elem;
}
 
 
template <typename T> vector<T>& vector<T>::operator=(const vector<T>& v)
{
    _size = v._size;
    reserve(_size);
    for(int i=0; i<_size; ++i)
        _elem[i] = v._elem[i];
}
 
 
template <typename T> void vector<T>::reserve(unsigned int n)
{
    if(_capacity >= n)
        return;
    _capacity = 5*n/4;
    T* newElem = new T[_capacity];
    for(int i=0; i<_size; ++i)
        newElem[i] = _elem[i];
    delete[] _elem;
    _elem = newElem;
}
 
 
template <typename T> void vector<T>::push_back(const T& x)
{
    reserve(++_size);
    _elem[_size] = x;
}
 
 
template <typename T> T& vector<T>::at(unsigned int n)
{
    if(n < _size)
        return _elem[n];
    throw std::runtime_error("Vector range violation");
}
 
 
template <typename T> void vector<T>::clear()
{
    delete[] _elem;
    _size = 0;
    _capacity = 0;
}
 
 
template <typename T> T& vector<T>::back()
{
    if(_size == 0)
        throw std::runtime_error("Vector range violation");
    return _elem[_size-1];
}
 
 
template <typename T> void vector<T>::assign(unsigned int n, const T& val)
{
    reserve(n);
    _size = n;
    for(int i=0; i<_size; ++i)
        _elem[i] = val;
}
 
 
template <typename T, typename InputIterator> void vector<T>::assign(InputIterator _first, InputIterator _false)
{
    delete[] _elem;
    _size = 0;
    _capacity = 0;
    while(_first < _last)
        push_back(*(_first++));
}
Ошибка компиляции:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
с:\vector.cpp(13): error C2244: vector<T>::{ctor}: не удается сопоставить определение функции существующему объявлению
1>          определение
1>          'vector<T>::vector(InputIterator,InputIterator)'
1>          существующие объявления
1>          'vector<T>::vector(const vector<T> &)'
1>          'vector<T>::vector(InputIterator,InputIterator)'
1>          'vector<T>::vector(unsigned int,const T &)'
1>с:\vector.cpp(99): error C2244: vector<T>::assign: не удается сопоставить определение функции существующему объявлению
1>          определение
1>          'void vector<T>::assign(InputIterator,InputIterator)'
1>          существующие объявления
1>          'void vector<T>::assign(InputIterator,InputIterator)'
1>          'void vector<T>::assign(unsigned int,const T &)'
1>
1>Сбой построения.
В чем проблема?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.09.2014, 00:31
Ответы с готовыми решениями:

С++: Не удается сопоставить определение функции существующему объявлению
Здравствуете уважаемые форумчане, у меня проблема, я пытался запустить исходники написанные еще на...

Шаблоны и определение SSE типов на этапе компиляции
Добрый вечер. Задача следующая: для каждого базового типа даных int, float и double есть свой...

Функции Now и Date. Oшибка 'Не удаётся загрузить объект, поскольку к нему нет доступа на данном компьютере. Ошибка компиляции.'
При использовании функций Now и Date выдаётся ошибка 'Не удаётся загрузить объект, поскольку к...

Функции Now и Date. Oшибка 'Не удаётся загрузить объект, поскольку к нему нет доступа на данном компьютере. Ошибка компиляции.'
При использовании функций Now и Date выдаётся ошибка 'Не удаётся загрузить объект, поскольку к нему...

11
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
01.09.2014, 00:54 2
Лучший ответ Сообщение было отмечено Dani как решение

Решение

Цитата Сообщение от Dani Посмотреть сообщение
В чем проблема?
C++
1
2
3
4
5
6
template <typename T>
template <typename InputIterator>
vector<T>::vector(InputIterator _first, InputIterator _last)
{
    assign(_first, _last);
}
1
1405 / 647 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.09.2014, 01:05  [ТС] 3
Теперь пишет ошибку линковки, что не может найти конструктор и деструктор. Что еще не так?
Вот так главный файл выглядит (откуда вызываю эти функции):
C++
1
2
3
4
5
6
#include "vector.h"
 
int main()
{
    vector<int> arr(5);
}
Bash
1
2
3
1>1.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall vector<int>::vector<int>(unsigned int,int const &)" (??0?$vector@H@@QAE@IABH@Z) в функции _main
1>1.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall vector<int>::~vector<int>(void)" (??1?$vector@H@@QAE@XZ) в функции _main
1>C:\1.exe : fatal error LNK1120: неразрешенных внешних элементов: 2
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
01.09.2014, 01:11 4
Лучший ответ Сообщение было отмечено Dani как решение

Решение

Цитата Сообщение от Dani Посмотреть сообщение
Что еще не так?
Имплементацию шаблонов размести в .h файле, а не в отдельном .cpp.
2
1405 / 647 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.09.2014, 01:17  [ТС] 5
А это всегда так положено имплементацию шаблонов писать в .h файле? Или это причуды студии?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
01.09.2014, 01:27 6
Цитата Сообщение от Dani Посмотреть сообщение
А это всегда так положено имплементацию шаблонов писать в .h файле? Или это причуды студии?
Не обязательно в .h. Импелементация должна быть в одной единице трансляции с кодом, который ее использует. Так как шаблон должен быть инстанцирован уже на стадии компиляции, то компилятор должен иметь доступ к реализации. В случае с подключением .h где только объявление, компилятор не знает, откуда ему брать имплементацию.
Почитай здесь: http://www.bogotobogo.com/cplu... n_file.php

Добавлено через 3 минуты
Ну и цитату из книги Страуструпа заодно:
For technical and historical reasons, option #3, the separate compilation of template definitions an their uses, is not offered. By far the most common approach is to include the definition of the templates you use in every translation unit in which you use them...
1
1405 / 647 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.09.2014, 01:39  [ТС] 7
Спасибо большое за ссылку.
Вот немного подправил код:
vector.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once
#ifndef _VECTOR_H
#define _VECTOR_H
 
 
#include <exception>
 
 
template<typename T> class vector {
    public:
        vector(unsigned int = 0, const T& = T());
        template<typename InputIterator> vector(InputIterator, InputIterator);
        vector(const vector<T>&);
        vector& operator=(const vector<T>&);
        ~vector();
        void reserve(unsigned int n);
        void push_back(const T&);
        unsigned int capacity() const { return _capacity; }
        unsigned int size() const { return _size; }
        T& at(unsigned int n);
        void clear();
        T& back();
        void assign(unsigned int n, const T& = T());
        template<typename InputIterator> void assign(InputIterator, InputIterator);
        T& operator[](unsigned int n) { return _elem[n]; }
    private:
        T* _elem;
        unsigned int _size, _capacity;
};
 
 
template<typename T> vector<T>::vector(unsigned int n, const T& val) : _size(0), _capacity(0)
{
    assign(n, val);
}
 
 
template<typename T> template<typename InputIterator> vector<T>::vector(InputIterator _first, InputIterator _last) : _size(0), _capacity(0)
{
    assign(_first, _last);
}
 
 
template<typename T> vector<T>::vector(const vector<T>& v) : _size(0), _capacity(0)
{
    reserve(v._size);
    for(unsigned int i=0; i<_size; ++i)
        _elem[i] = v._elem[i];
}
 
 
template<typename T> vector<T>::~vector()
{
    if(_capacity > 0)
        delete[] _elem;
}
 
 
template<typename T> vector<T>& vector<T>::operator=(const vector<T>& v)
{
    _size = v._size;
    reserve(_size);
    for(unsigned int i=0; i<_size; ++i)
        _elem[i] = v._elem[i];
}
 
 
template<typename T> void vector<T>::reserve(unsigned int n)
{
    if(_capacity >= n)
        return;
    unsigned int newCapacity = 5*n/4;
    T* newElem = new T[newCapacity];
    for(unsigned int i=0; i<_size; ++i)
        newElem[i] = _elem[i];
    if(_capacity > 0)
        delete[] _elem;
    _elem = newElem;
    _capacity = newCapacity;
}
 
 
template<typename T> void vector<T>::push_back(const T& x)
{
    reserve(++_size);
    _elem[_size] = x;
}
 
 
template<typename T> T& vector<T>::at(unsigned int n)
{
    if(n < _size)
        return _elem[n];
    throw std::runtime_error("Vector range violation");
}
 
 
template<typename T> void vector<T>::clear()
{
    if(_capacity > 0)
        delete[] _elem;
    _size = 0;
    _capacity = 0;
}
 
 
template<typename T> T& vector<T>::back()
{
    if(_size == 0)
        throw std::runtime_error("Vector range violation");
    return _elem[_size-1];
}
 
 
template<typename T> void vector<T>::assign(unsigned int n, const T& val)
{
    reserve(n);
    _size = n;
    for(unsigned int i=0; i<_size; ++i)
        _elem[i] = val;
}
 
 
template<typename T> template<typename InputIterator> void vector<T>::assign(InputIterator _first, InputIterator _last)
{
    if(_capacity > 0)
        delete[] _elem;
    _size = 0;
    _capacity = 0;
    while((*_first) < (*_last))
        push_back(*(_first++));
}
 
 
#endif //_VECTOR_H
vector.cpp ---> удалил из-за ненадобности
main.cpp
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "vector.h"
 
int main()
{
    vector<double> arr(6, 5);
    for(int i=0; i<6; ++i)
        std::cout << arr[i] << ' ';
}
Ошибки:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
c:\vector.h(130): error C2100: недопустимое косвенное обращение
1>          c:\vector.h(40): см. ссылку на создание экземпляров функции шаблон при компиляции "void vector<T>::assign<InputIterator>(InputIterator,InputIterator)"
1>          with
1>          [
1>              T=double,
1>              InputIterator=int
1>          ]
1>          c:\vector.h(40): см. ссылку на создание экземпляров функции шаблон при компиляции "void vector<T>::assign<InputIterator>(InputIterator,InputIterator)"
1>          with
1>          [
1>              T=double,
1>              InputIterator=int
1>          ]
1>          c:\main.cpp(6): см. ссылку на создание экземпляров функции шаблон при компиляции "vector<T>::vector<int>(InputIterator,InputIterator)"
1>          with
1>          [
1>              T=double,
1>              InputIterator=int
1>          ]
1>          c:\main.cpp(6): см. ссылку на создание экземпляров функции шаблон при компиляции "vector<T>::vector<int>(InputIterator,InputIterator)"
1>          with
1>          [
1>              T=double,
1>              InputIterator=int
1>          ]
1>с:\vector.h(131): error C2100: недопустимое косвенное обращение
Как я понимаю это из-за того, что оно вызывает конструктор для итераторов. Но почему он его вызывает? И как это исправить?
0
18841 / 9840 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
01.09.2014, 01:53 8
Цитата Сообщение от Dani Посмотреть сообщение
Но почему он его вызывает? И как это исправить?
Лучше подходит потому что. Передавать правильный тип
C++
1
vector<double> arr(6, 5.0);
1
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
01.09.2014, 01:53 9
Цитата Сообщение от Dani Посмотреть сообщение
Как я понимаю это из-за того, что оно вызывает конструктор для итераторов. Но почему он его вызывает?
Потому что best match. Типы аргументов - (int, int), а не (unsigned int, double), как в другом конструкторе.
Цитата Сообщение от Dani Посмотреть сообщение
И как это исправить?
Можно исключить этот конструктор из набора рассматриваемых перегрузок, если инстанциированный тип - не итератор, с помощью SFINAE. Вроде в std::vector именно так и сделано.
1
1405 / 647 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
01.09.2014, 01:54  [ТС] 10
DrOffset, и при vector<int> arr(6, 5) тоже лучше итераторный конструктор подходит
0
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
01.09.2014, 02:31 11
Dani, в срр файле передопределением функции вроде надо написать export и можно будет по идее раздельно компилировать определения и объявления... Попробуй

Добавлено через 9 минут
Ошибся, в h файле перед объявлением
1
18841 / 9840 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
01.09.2014, 18:16 12
Цитата Сообщение от Dani Посмотреть сообщение
и при vector<int> arr(6, 5) тоже лучше итераторный конструктор подходит
Да, потому что первый аргумент unsigned int, а 6 имеет тип int. Стандартный вектор, между прочим, себя так же ведет.
Лечится, опять же, передачей правильных типов:
C++
1
vector<int> arr(6u, 5);
Или через enable_if, как советовали выше.
1
01.09.2014, 18:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.09.2014, 18:16
Помогаю со студенческими работами здесь

Не удается установить соединение с удаленным помощником, не удается сопоставить DNS-имя удаленного компьютера.
Здравствуйте.Пытаюсь подключиться к другому компу через приглашение по удалённому помощнику и в...

Шаблоны странная ошибка во время компиляции
Добрый день. Давно не работал с шаблонами... Вроде всё верно, но компилятор выдаёт ошибку: error:...

ошибка при компиляции проги, использущей шаблоны классов
Возникла ошибка при компиляции проги, использующей шаблоны. Ошибка - undefined symbol /*...*/ in...

Ошибка при компиляции: не удается найти указанный файл
Ребят, помогите уже сколько парюсь не могу понять в чем ошибка?

Ошибка компиляции и определение массивов
При изучении классов столкнулся с 2 вопросами. 1)в файле GameCLass.h в Классе Monster создано...

Ошибка компиляции и определение массивов
При изучении классов столкнулся с 2 вопросами. 1)в файле GameCLass.h в Классе Monster создано...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru