powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка вызова функции из шаблона класса
13 сообщений из 13, страница 1 из 1
Ошибка вызова функции из шаблона класса
    #38241931
pol_ar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемые форумчане,
небольшой вопрос по синтаксису для тех, кто в танке. Имеется шаблон класса, в котором объявлена функция SetValues. На этапе компиляции возникает ошибка линковки. Ошибка происходит уже при вызове функции объекта класса, созданного на основе шаблона. Текст ошибки следующий:
"error LNK2019: ссылка на неразрешенный внешний символ "public: void __thiscall test6_template<int>::SetValues(int,int)" (?SetValues@?$test6_template@H@@QAEXHH@Z) в функции "void __cdecl ReadItems(void)" (?ReadItems@@YAXXZ)c:\vs\ItemClassCore\ItemClassCore.obj"
В чем может быть причина?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
// test6_template.cpp
template <class T_item> class test6_template
{
private:
	T_item name, counter;
public:
	void SetValues(T_item a, T_item b);
};

// test6_template.cpp
template <class T_item>
	void test6_template<T_item>::SetValues(T_item a, T_item b): name(a), counter(b){}

// main.cpp
	test6_template<int> t2; // правильно
	t2.SetValues(13,15); // ОШИБКА
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242015
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pol_ar,

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

Код: plaintext
1.
2.
3.
4.
5.
// test6_template.cpp
template <class T_item>
	void test6_template<T_item>::SetValues(T_item a, T_item b): name(a), counter(b){}

template	class test6_template<int>; // явное инстанцирования типом int




Альтернатива этому - помещать определения тел методов в заголовке, там же где описан класс. Но это не всегда удобно, т.к. увеличивается зависимость между модулями и время компиляции.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242056
То что Anatoly Moskovsky сказал и ещё:
pol_arУважаемые форумчане,
небольшой вопрос по синтаксису для тех, кто в танке. Имеется шаблон класса, в котором объявлена функция SetValues. На этапе компиляции возникает ошибка линковки. Ошибка происходит уже при вызове функции объекта класса, созданного на основе шаблона. Текст ошибки следующий:
"error LNK2019: ссылка на неразрешенный внешний символ "public: void __thiscall test6_template<int>::SetValues(int,int)" (?SetValues@?$test6_template@H@@QAEXHH@Z) в функции "void __cdecl ReadItems(void)" (?ReadItems@@YAXXZ)c:\vs\ItemClassCore\ItemClassCore.obj"
В чем может быть причина?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
// test6_template.cpp
template <class T_item> class test6_template
{
private:
	T_item name, counter;
public:
	void SetValues(T_item a, T_item b);
};

// test6_template.cpp
template <class T_item>
	void test6_template<T_item>::SetValues(T_item a, T_item b): 
name(a), counter(b) 
{ name = a, counter = b; }

// main.cpp
	test6_template<int> t2; // правильно
	t2.SetValues(13,15); // ОШИБКА


only constructors take member initializers
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242057
name(a), counter(b)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл вычеркнуть :)
name(a), counter(b)
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242062
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pol_ar,

Извините, а почему вы при определении метода SetValues() используете синтаксис, который допустим только в конструкторах?
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242066
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pol_ar,

Уточню.

Вот так можно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
class foo
{
    int i;
public:
    foo():
        i()
    {}
};


А вот так нельзя:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
class foo
{
    int i;
public:
    foo()   {}
    Reset():
        i()
    {}
};
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242080
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskypol_ar,

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

Альтернатива этому - помещать определения тел методов в заголовке, там же где описан класс. Но это не всегда удобно, т.к. увеличивается зависимость между модулями и время компиляции.
Разве?

Инстанцировать (явно) методы надо не "всеми потенциальными типами-параметрами шаблона", а теми типами для которых это нужно... Например, для оптимизации или контроля что бы не для всех типов инстанцировалось.

Мы можем "объявить инстанцирование в .h", а реализовать его в .cpp.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242096
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravИнстанцировать (явно) методы надо не "всеми потенциальными типами-параметрами шаблона", а теми типами для которых это нужно... Например, для оптимизации или контроля что бы не для всех типов инстанцировалось.

Мы можем "объявить инстанцирование в .h", а реализовать его в .cpp.
Так как я написал выше - правильно. (Естественно инстанцировать надо не вообще всеми возможными типами, а именно потенциально используемыми с этим шаблоном)

Вы не можете инстанцировать шаблон там, где нет реализации.
Что такое "объявить инстанцирование" я не знаю.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242103
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЧто такое "объявить инстанцирование" я не знаю.
Имелось в виду в .h объявить конкретизированный вариант функции foo<int>(); -- просто объявление. А определение foo<int>(); оставить в отдельной единице компиляции.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38242107
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravAnatoly MoskovskyЧто такое "объявить инстанцирование" я не знаю.
Имелось в виду в .h объявить конкретизированный вариант функции foo<int>(); -- просто объявление. А определение foo<int>(); оставить в отдельной единице компиляции.
Это вы путаете со специализацией. При специализации это возможно. Но бессмысленно, т.к. специализация сама по себе устраняет данную проблему (если она не частичная).
А в данном топике обычный неспециализированный шаблон.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38243588
pol_ar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
petravpol_ar,
Извините, а почему вы при определении метода SetValues() используете синтаксис, который допустим только в конструкторах?

Да, вы правы. При сокращении кода внес ошибку. Это и есть конструктор.
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38243830
pol_ar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Какое-то решение по этому вопросу мне удалось найти. Помог перенос определения конструктора в заголовочный файл, причем объявление и определение разнесены друг от друга, т.е. синтаксис все же был правильный.
Если нет других версий, то будем считать это ошибкой компилятора Visual Studio 2010, который для обычных классов заглядывает в соответствующий *.cpp файл, чтобы найти тело (определение) метода, а для шаблонов "забывает" это сделать.
Вот окончательный текст шаблона:

Код: plaintext
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.
// test6_template.h
template <class T_item> class test6_template
//template <typename T_item> class test6_template // так тоже работает
{
private:
	T_item name, counter;
public:
	T_item GetName() {return name;}
	T_item GetCounter();// {return counter;} // так тоже работает
	test6_template(T_item a, T_item b) {name = a; counter = b;}

	test6_template(void){}
	~test6_template(void){}
};

template <class T_item> 
	T_item // возвращаемое значение
	test6_template<T_item>::GetCounter()
{
	return counter;
}
// main.cpp
	...
	test6_template<int> t2(13,15);
	cout << t2.GetCounter();
...
Рейтинг: 0 / 0
Ошибка вызова функции из шаблона класса
    #38243861
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pol_arЕсли нет других версий, то будем считать это ошибкой компилятора Visual Studio 2010, который для обычных классов заглядывает в соответствующий *.cpp файл, чтобы найти тело (определение) метода, а для шаблонов "забывает" это сделать.
это не ошибка компилятора, а поведение, регламентируемое стандартом.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка вызова функции из шаблона класса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]