19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
1

Объявление и определение шаблонного класса

04.04.2015, 23:13. Показов 3384. Ответов 16
Метки нет (Все метки)

Добрый вечер, мастера
Почему данный код вызывает проблемы у компилятора?
C++
1
2
3
4
5
6
7
8
// class.h
template <typename T>
class Name
{
    //...
    void func(int);
    //...
};
C++
1
2
3
4
5
6
// class.cpp
template<typename T>
void Name<T>::func(int i)
{
    //...
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.04.2015, 23:13
Ответы с готовыми решениями:

Объявление шаблонного класса
Как объявить шаблонный класс?

Объявление наследника шаблонного класса
как объявить наследника шаблонного класса, да ещё если он обрамлён собственным пространсвом имён?...

Определение методов шаблонного класса
Столкнулся с такой проблемой, реализовываю итератор для шаблонного списка, при определении метода...

Определение типа члена шаблонного класса
Такая проблема. Есть шаблонный класс с членом - указателем, тип которого должен определяться в...

16
Эксперт С++
8719 / 4262 / 950
Регистрация: 15.11.2014
Сообщений: 9,669
04.04.2015, 23:32 2
Цитата Сообщение от Mistik Посмотреть сообщение
Почему данный код вызывает проблемы у компилятора?
потому что компиляторы пока ещё не осилили экспорт шаблонов.
0
244 / 164 / 133
Регистрация: 30.09.2012
Сообщений: 690
04.04.2015, 23:33 3
Mistik, Описание членов-функций шаблонного класса и сам шаблонный класс должны находиться в одном файле
0
Эксперт С++
8719 / 4262 / 950
Регистрация: 15.11.2014
Сообщений: 9,669
04.04.2015, 23:35 4
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
Mistik, Описание членов-функций шаблонного класса и сам шаблонный класс должны находиться в одном файле
вы ошибаетесь.
0
19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
04.04.2015, 23:36  [ТС] 5
Gr1f0nn, hoggy, благодарю.

А возможно ли определение и объявление перегрузки оператора разделить?
Т.е.
C++
1
friend ostream& operator<<(ostream&, Name<T>&);
и
C++
1
2
3
4
5
template <typename T>
ostream& operator<<(ostream& out, Name<T>& obj)
{
 
}
или как сделать правильно?
0
Эксперт С++
8719 / 4262 / 950
Регистрация: 15.11.2014
Сообщений: 9,669
04.04.2015, 23:38 6
Цитата Сообщение от Mistik Посмотреть сообщение
А возможно ли определение и объявление перегрузки оператора разделить?
перетащите все из cpp файла в хэдэр.
cpp файл уничтожьте.
0
244 / 164 / 133
Регистрация: 30.09.2012
Сообщений: 690
04.04.2015, 23:42 7
hoggy, Почему? Если, например, объявить шаблонный класс в .h , а его функции описать в .cpp, то выдаст ошибку или я не прав?

Добавлено через 1 минуту
В каких случаях тогда можно объявить в разных файлах?


Полное описание шаблона должно быть известно до его использования. Следовательно, нельзя разбить объявление и реализацию на .cpp и .h файлы, вся реализация должна быть известна и находиться в .h файле. Это объясняется тем, что .cpp файлы компилируются отдельно и независимо друг от друга. Это громоздко, однако в пределах одного .h файла можно сначала написать объявление, вынеся описание в конец файла:
0
19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
04.04.2015, 23:43  [ТС] 8
Цитата Сообщение от hoggy Посмотреть сообщение
перетащите все из cpp файла в хэдэр.
cpp файл уничтожьте.
я и пытаюсь это сделать в хедере (вытаскиваю код из класса)
C++
1
friend ostream& operator<<(ostream&, Name<T>&);
C++
1
2
3
4
5
template <typename T>
ostream& operator<<(ostream& out, Name<T>& obj)
{
 
}
Ошибка:
Цитата Сообщение от Microsoft VS
error LNK2019: ссылка на неразрешенный внешний символ
0
16088 / 8688 / 2122
Регистрация: 30.01.2014
Сообщений: 14,975
04.04.2015, 23:47 9
Цитата Сообщение от Mistik Посмотреть сообщение
Ошибка:
В классе надо так:
C++
1
2
    template <typename Tp>
    friend std::ostream& operator<<(std::ostream&, Name<Tp>&);
Вне класса так:
C++
1
2
3
4
5
template <typename Tp>
std::ostream& operator<<(std::ostream& out, Name<Tp>& obj)
{
 
}
1
19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
04.04.2015, 23:50  [ТС] 10
DrOffset, господи, глупая ошибка. А я то думаю, в чём трабла..
Совсем забыл, что friend методы, не считаются методами класса
0
16088 / 8688 / 2122
Регистрация: 30.01.2014
Сообщений: 14,975
04.04.2015, 23:55 11
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
Полное описание шаблона должно быть известно до его использования.
Это ключевое, только не использования, а инстанцирования. Использовать можно по-разному. Технически это могут быть разные файлы. Например иногда я делаю так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Этот класс находится в файле some.h
class Some
{
public:
    void foo();
    void boo();
 
private:
    // этот метод внутренний, никакие другие классы не могут с ним работать,
    // следовательно его реализацию можно поместить в cpp файл some.cpp,
    // где находится реализация остальных нешаблонных методов, там
    // она может ими свободно использоваться
    template <typename T1>
    void someInternalMethod(T1 const &);
};
А еще есть понятие "явное инстанцирование". Которое позволяет сгенерировать инстанцию для заранее известных аргументов в том месте, где доступно тело шаблона. А в остальных местах, где шаблон с этими аргументами будет использоваться, его реализацию не предоставлять.
А еще в С++11 есть extern template.
2
244 / 164 / 133
Регистрация: 30.09.2012
Сообщений: 690
04.04.2015, 23:58 12
hoggy, я правильно понимаю, что причина моей ошибки в этом:

If you are working with a compiler that supports the export keyword, it will probably continue to support the keyword via some sort of compiler option or extension until its users migrate away from it. If you already have code that uses export, you can use a fairly simple discipline to allow your code to easily migrate if/when your compiler stops supporting it entirely. Just define your template header-files like this:
C++
1
2
3
4
5
6
7
8
9
10
11
// File Foo.h
#ifdef USE_EXPORT_KEYWORD
export
#endif
template<typename T>
class Foo {
  // ...
};
#ifndef USE_EXPORT_KEYWORD
  #include "Foo.cpp"
#endif
And define your non-inline functions in a source-file like this:

C++
1
2
3
4
5
// File Foo.cpp
#ifdef USE_EXPORT_KEYWORD
export
#endif
template<typename T> ...
Then compile with -DUSE_EXPORT_KEYWORD, or whatever equivalent compiler option lets you set a preprocessor symbol like USE_COMPILER_KEYWORD, and if/when your compiler removes support for export, just remove that compiler option.
Добавлено через 2 минуты
DrOffset, Спасибо, не знал такого
0
2548 / 1207 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
04.04.2015, 23:59 13
Шаблоны функций
0
Эксперт С++
8719 / 4262 / 950
Регистрация: 15.11.2014
Сообщений: 9,669
05.04.2015, 00:01 14
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
причина моей ошибки в этом:
см #11 сообщения от господина DrOffset.
0
19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
05.04.2015, 00:08  [ТС] 15
Инстанцирование - это:
C++
1
2
template <typename T>
void func(T t) {}
так?
А это явное инстанцирование:
C++
1
typedef std::vector<int> intVector;
Верно?
0
16088 / 8688 / 2122
Регистрация: 30.01.2014
Сообщений: 14,975
05.04.2015, 00:14 16
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
я правильно понимаю, что причина моей ошибки в этом
export template - в С++03 была такая возможность, которая позволяла получить "честное" разделение по единицам трансляции. До сих пор в полном объему эту возможность реализовали только ребята из comeau computing (вследствие ее крайней сложности в реализации). Но в новом стандарте С++11 этой возможности нет, а export template объявлен deprecated. Фича не прижилась. Само ключевое слово export изъято из списка ключевых слов C++, но зарезервировано для будущего использования.

Добавлено через 4 минуты
Цитата Сообщение от Mistik Посмотреть сообщение
А это явное инстанцирование:
C++
1
typedef std::vector<int> intVector;
Нет. Это вообще не инстанцирование. Инстанцирование будет, когда ты intVector начнешь использовать. Например определишь переменную такого типа.
А явное инстацирование - это вот:
C++
1
template class std::vector<int>;
0
19 / 19 / 14
Регистрация: 25.02.2015
Сообщений: 138
05.04.2015, 00:20  [ТС] 17
Цитата Сообщение от DrOffset Посмотреть сообщение
template class std::vector<int>;
пока что никогда не встречал такой записи. Но спасибо за разъяснение
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.04.2015, 00:20
Помогаю со студенческими работами здесь

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра?
header.h template &lt;class T&gt; class MyVector { public: void swap(MyVector&lt;T&gt;Vector); }...

Определение методов шаблонного класса в файле реализации
Доброго времени суток, форумчане! :) Поздравляю всех мужчин с праздником. Желаю быть...

объявление и определение функции класса
почему не компилируется #include &lt;iostream&gt; int main(){ class A { public: A(); //...

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


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru