template static methods
От: anagaf  
Дата: 16.10.09 10:04
Оценка: 1 (1)
У меня есть шаблонная функция, определенная прямо в cpp-файле, например:

template<class Object> bool test( Object obj) { return (obj != 0);}


она вызывается в том же cpp, все работает. Теперь я хочу запихать эту функцию как статическую в отдельный класс, чисто для удобства:

class Tester
{
public:
template<class Object> static bool test( Object obj) { return (obj != 0);}
}


Вызов прописан как:

Tester::test<Node*>(node)


Компиляция проходит, а линковка выдает "unresolved external symbol public: static bool Tester::test..."

Что я делаю не так?
Re: template static methods
От: hramovnik  
Дата: 16.10.09 10:34
Оценка:
Здравствуйте, anagaf, Вы писали:

A>У меня есть шаблонная функция, определенная прямо в cpp-файле, например:


A>
A>template<class Object> bool test( Object obj) { return (obj != 0);}
A>


A>она вызывается в том же cpp, все работает. Теперь я хочу запихать эту функцию как статическую в отдельный класс, чисто для удобства:


A>
A>class Tester
A>{
A>public:
A>template<class Object> static bool test( Object obj) { return (obj != 0);}
A>}
A>


A>Вызов прописан как:


A>
A>Tester::test<Node*>(node)
A>


A>Компиляция проходит, а линковка выдает "unresolved external symbol public: static bool Tester::test..."


A>Что я делаю не так?



//file: test.h
template<class T>
class CMyClass
{
public:

/*some code*/

static bool test(T & obj)
{

/*some code*/

return true/*false*/;
}
}

У меня такой вариант работает без проблем.
Re: template static methods
От: Vain Россия google.ru
Дата: 16.10.09 10:40
Оценка: -2
Здравствуйте, anagaf, Вы писали:

A>
A>template<class Object> bool test( Object obj) { return (obj != 0);}
A>

A>она вызывается в том же cpp, все работает. Теперь я хочу запихать эту функцию как статическую в отдельный класс, чисто для удобства:
A>
A>class Tester
A>{
A>public:
A>template<class Object> static bool test( Object obj) { return (obj != 0);}
A>}
A>

A>Вызов прописан как:
A>
A>Tester::test<Node*>(node)
A>

A>Компиляция проходит, а линковка выдает "unresolved external symbol public: static bool Tester::test..."
A>Что я делаю не так?
Если надо, чтобы из другого модуля было видно, то на определение класса повесить __declspec(dllexport/dllimport). Но у вас она ещё и шаблонная, а для таких общего метода не существует. Можно попробывать насоздавать инстанций:
//Tester.h
class __declspec(dllexport) Tester
{
public:
  template<class T> static bool test( T obj);
};

template<class T>
bool Tester::test( T obj)
{ return (obj != 0);}

//Tester.cpp
template<> bool Tester::test<short>(short);
template<> bool Tester::test<int>(int);
template<> bool Tester::test<long>(long);
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 11:04
Оценка: -1
Здравствуйте, anagaf, Вы писали:

A>У меня есть шаблонная функция, определенная прямо в cpp-файле, например:


A>
A>template<class Object> bool test( Object obj) { return (obj != 0);}
A>


A>она вызывается в том же cpp, все работает. Теперь я хочу запихать эту функцию как статическую в отдельный класс, чисто для удобства:


A>
A>class Tester
A>{
A>public:
A>template<class Object> static bool test( Object obj) { return (obj != 0);}
A>}
A>


A>Вызов прописан как:


A>
A>Tester::test<Node*>(node)
A>


A>Компиляция проходит, а линковка выдает "unresolved external symbol public: static bool Tester::test..."


A>Что я делаю не так?

1) Может ты шаблон вынес в cpp
2) Может node константный
3) может компилятор обрезанный
<Подпись удалена модератором>
Re[2]: template static methods
От: anagaf  
Дата: 16.10.09 11:16
Оценка:
Здравствуйте, denisko, Вы писали:

D>1) Может ты шаблон вынес в cpp


Да, в начальном сообщении была ошибка. Tester::test() определена в cpp, как:

template <class Object> bool Tester::test( Object obj)
{
    return obj != 0;
}


Ты это имел ввиду? Что криминального в таком определении?

Если прописать прямо в h:

template <class Object> static bool test( Object obj) {return obj != 0;}


все работает
Re[2]: template static methods
От: anagaf  
Дата: 16.10.09 11:21
Оценка:
Здравствуйте, Vain, Вы писали:

V>//Tester.cpp
V>template<> bool Tester::test<short>(short);
V>template<> bool Tester::test<int>(int);
V>template<> bool Tester::test<long>(long);


Но совсем понимаю смысл этого кода? Его куда надо вставлять, туда где функция определена (tester.cpp) или туда, где она вызывается (скажем, main.cpp)?
Впрочем, я попробовал и туда, и туда — не помогла

Да, в начальном сообщении была ошибка. Tester::test() определена в не в объявлении класса, а в tester.cpp, как:

template <class Object> bool Tester::test( Object obj)
{
return obj != 0;
}
Re[3]: template static methods
От: hramovnik  
Дата: 16.10.09 11:23
Оценка:
Здравствуйте, anagaf, Вы писали:

A>Здравствуйте, denisko, Вы писали:


D>>1) Может ты шаблон вынес в cpp


A>Да, в начальном сообщении была ошибка. Tester::test() определена в cpp, как:


A>
A>template <class Object> bool Tester::test( Object obj)
A>{
A>    return obj != 0;
A>}
A>


A>Ты это имел ввиду? Что криминального в таком определении?


A>Если прописать прямо в h:


A>
A>template <class Object> static bool test( Object obj) {return obj != 0;}
A>


A>все работает


//file: test.h
/*...*/
template <class Object> 
class CTest
{
public:
    static bool test( Object obj);
/*...*/
}
/*...*/


//file: test.cpp
/*...*/
template <class Object>
bool Tester::test( Object obj)
{
    return obj != 0;
}
/*...*/


Попробуй так, если хочешь разделить объявление и опредиление.
Re[3]: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 11:25
Оценка:
Здравствуйте, anagaf, Вы писали:

A>Ты это имел ввиду? Что криминального в таком определении?


Низзя так. используй inl файл если хочешь разделить объявление и релизацию.
<Подпись удалена модератором>
Re[4]: template static methods
От: anagaf  
Дата: 16.10.09 11:38
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, anagaf, Вы писали:


A>>Ты это имел ввиду? Что криминального в таком определении?


D>Низзя так. используй inl файл если хочешь разделить объявление и релизацию.


Нельзя именно для статических шаблонных функций-членов?
Re[5]: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 11:40
Оценка:
Здравствуйте, anagaf, Вы писали:

A>Здравствуйте, denisko, Вы писали:


D>>Здравствуйте, anagaf, Вы писали:


A>>>Ты это имел ввиду? Что криминального в таком определении?


D>>Низзя так. используй inl файл если хочешь разделить объявление и релизацию.


A>Нельзя именно для статических шаблонных функций-членов?

Для любых шаблонов нельзя, есть костыли типа экспорта, но это жесть.
сделай проще объявление в .h код в .inl в конце h включаешь inl
<Подпись удалена модератором>
Re[6]: template static methods
От: hramovnik  
Дата: 16.10.09 11:48
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, anagaf, Вы писали:


A>>Здравствуйте, denisko, Вы писали:


D>>>Здравствуйте, anagaf, Вы писали:


A>>>>Ты это имел ввиду? Что криминального в таком определении?


D>>>Низзя так. используй inl файл если хочешь разделить объявление и релизацию.


A>>Нельзя именно для статических шаблонных функций-членов?

D>Для любых шаблонов нельзя, есть костыли типа экспорта, но это жесть.
D>сделай проще объявление в .h код в .inl в конце h включаешь inl

Код который я привел раньше
Автор: hramovnik
Дата: 16.10.09
не использует костыли и прекрасно работает.
Может я чего то не понял?
Re[7]: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 11:54
Оценка:
Здравствуйте, hramovnik, Вы писали:
H>Код который я привел прекрасно работает.
С чего ты это взял ?
<Подпись удалена модератором>
Re[8]: template static methods
От: hramovnik  
Дата: 16.10.09 12:01
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, hramovnik, Вы писали:

H>>Код который я привел прекрасно работает.
D>С чего ты это взял ?

С того, что сюда конечно я его писал по памяти, но в рабочем проекте подобный код работает без проблем.
Компилится как студией, так g++.
Подобным образом описаны общие, частично и полностью специализированные шаблоны. Вылетов нет, утечек тоже. Компилятор, компоновщик довольны. Я тоже
Re[9]: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 12:14
Оценка:
Здравствуйте, hramovnik, Вы писали:

H>Здравствуйте, denisko, Вы писали:


D>>Здравствуйте, hramovnik, Вы писали:

H>>>Код который я привел прекрасно работает.
D>>С чего ты это взял ?

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

Приведи подобный компилирующийся код.
<Подпись удалена модератором>
Re[7]: template static methods
От: anagaf  
Дата: 16.10.09 12:21
Оценка:
Здравствуйте, hramovnik, Вы писали:

H>Код который я привел раньше
Автор: hramovnik
Дата: 16.10.09
не использует костыли и прекрасно работает.

H>Может я чего то не понял?

Просто не хочется делать класс Tester шаблонным. Очень сложный шаблон может получиться, функций типа test несколько и у каждой по несколько параметров
Re[10]: template static methods
От: hramovnik  
Дата: 16.10.09 12:27
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, hramovnik, Вы писали:


H>>Здравствуйте, denisko, Вы писали:


D>>>Здравствуйте, hramovnik, Вы писали:

H>>>>Код который я привел прекрасно работает.
D>>>С чего ты это взял ?

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

D>Приведи подобный компилирующийся код.


Вот:
(под руку попался частично специализированный шаблон)
//file: .h
template<class T>
class CSpecificData
    : public CData
{
private:
    T & data;
/*...*/
public:
/*...*/
    static void SetValue(const std::string &value);
};

//file: .cpp

void CSpecificData<int>::SetValue(const std::string &value)
{
    /*...*/
}


Код из рабочего проекта, так что куски повырезал. Если сильно захочется скомпилить, ты уж, если чего не хватает, добавь
Re[8]: template static methods
От: hramovnik  
Дата: 16.10.09 12:30
Оценка:
Здравствуйте, anagaf, Вы писали:

A>Здравствуйте, hramovnik, Вы писали:


H>>Код который я привел раньше
Автор: hramovnik
Дата: 16.10.09
не использует костыли и прекрасно работает.

H>>Может я чего то не понял?

A>Просто не хочется делать класс Tester шаблонным. Очень сложный шаблон может получиться, функций типа test несколько и у каждой по несколько параметров


Так зачем тогда вообще засовывать функцию в класс?
Просто добавь в заголовочный файл объявление прототипа функции, а реализацию оставь как есть.
Re[11]: template static methods
От: denisko http://sdeniskos.blogspot.com/
Дата: 16.10.09 12:46
Оценка:
Здравствуйте, hramovnik, Вы писали:

H>Код из рабочего проекта, так что куски повырезал. Если сильно захочется скомпилить, ты уж, если чего не хватает, добавь

Какое отношение этот код имеет к проблеме? Предлагаешь автору для любого чиха шаблон специализировать? Генитальное решение.
<Подпись удалена модератором>
Re[12]: template static methods
От: hramovnik  
Дата: 16.10.09 12:48
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, hramovnik, Вы писали:


H>>Код из рабочего проекта, так что куски повырезал. Если сильно захочется скомпилить, ты уж, если чего не хватает, добавь

D>Какое отношение этот код имеет к проблеме? Предлагаешь автору для любого чиха шаблон специализировать? Генитальное решение.

Я же написал, что просто он попался под руку. я автору предлагаю не заморачиваться с классами.
Re[3]: template static methods
От: Vain Россия google.ru
Дата: 16.10.09 13:13
Оценка:
Здравствуйте, anagaf, Вы писали:

A>
V>>//Tester.cpp
V>>template<> bool Tester::test<short>(short);
V>>template<> bool Tester::test<int>(int);
V>>template<> bool Tester::test<long>(long);
A>


A>Но совсем понимаю смысл этого кода? Его куда надо вставлять, туда где функция определена (tester.cpp) или туда, где она вызывается (скажем, main.cpp)?

В tester.cpp.
A>Впрочем, я попробовал и туда, и туда — не помогла
A>Да, в начальном сообщении была ошибка. Tester::test() определена в не в объявлении класса, а в tester.cpp, как:
И класс и шаблонная функция должны быть опеределёны в h файле. В противном случае линковщик не сможет найти в obj файлах инстанции этой функции.
Пример выше обеспечивает явное инстанцирование, а не инстанцирование по вызову. Если в вашем случае оно не работает значет вы пытаетесь вызвать инстанцию шаблонной функции, которая не инстанцирована в модуле.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.