специализация шаблона - усталая голова форуму покоя не даёт
От: Molchalnik  
Дата: 24.08.14 14:13
Оценка:
Прошу прощения, конец дня, работаю без выходных, туплю сильно и прекрасно осознаю, что задаю дурацкий вопрос. Но обычно у меня проблем с шаблонами не возникает, я считаю, что хорошо разбираюсь в них.

И тем не менее,
namespace some {
template <typename Tn> Tn* CO(Tn *) {return NULL;}
template <> GenlOps* CO<GenlOps>(GenlOps*) {return NULL;}
template <> Semaphore* CO<Semaphore>(Semaphore*) {return NULL;}
}


дают ошибку на этапе линкования. "multiply definition".

эти строки в заголовочнике, который подключается к двум cpp файлам
Re: специализация шаблона - усталая голова форуму покоя не даёт
От: Ops Россия  
Дата: 24.08.14 15:26
Оценка:
Здравствуйте, Molchalnik, Вы писали:

Вынести специализацию в 3-й файл?

14.7.5 For a given template and a given set of template-arguments,
— an explicit instantiation definition shall appear at most once in a program,
— an explicit specialization shall be defined at most once in a program (according to 3.2), and
— both an explicit instantiation and a declaration of an explicit specialization shall not appear in a
program unless the explicit instantiation follows a declaration of the explicit specialization.

Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re: специализация шаблона - усталая голова форуму покоя не даёт
От: Abyx Россия  
Дата: 24.08.14 15:38
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Прошу прощения, конец дня, работаю без выходных, туплю сильно и прекрасно осознаю, что задаю дурацкий вопрос. Но обычно у меня проблем с шаблонами не возникает, я считаю, что хорошо разбираюсь в них.


M>И тем не менее,

M>
M>namespace some {
M>template <typename Tn> Tn* CO(Tn *) {return NULL;}
M>template <> GenlOps* CO<GenlOps>(GenlOps*) {return NULL;}
M>template <> Semaphore* CO<Semaphore>(Semaphore*) {return NULL;}
M>}
M>


M>дают ошибку на этапе линкования. "multiply definition".


M>эти строки в заголовочнике, который подключается к двум cpp файлам


добавь inline или static.
In Zen We Trust
Re[2]: специализация шаблона - усталая голова форуму покоя не даёт
От: Molchalnik  
Дата: 24.08.14 22:51
Оценка: :)
Здравствуйте, Abyx, Вы писали:


A>добавь inline или static.

К шаблону-то? Думаешь, сработает? А зачем? Шаблоны не требуют инлайна и вряд ли могут быть статик
Re[2]: специализация шаблона - усталая голова форуму покоя не даёт
От: Molchalnik  
Дата: 24.08.14 22:52
Оценка:
Здравствуйте, Ops, Вы писали:

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


Ops>Вынести специализацию в 3-й файл?

ты что имеешь в виду?
Re[3]: специализация шаблона - усталая голова форуму покоя не даёт
От: flаt  
Дата: 25.08.14 05:00
Оценка:
Здравствуйте, Molchalnik, Вы писали:

A>>добавь inline или static.

M>К шаблону-то?
template <> GenlOps* CO<GenlOps>(GenlOps*) {return NULL;}
Уже не шаблон, нет?

M>Думаешь, сработает? А зачем? Шаблоны не требуют инлайна и вряд ли могут быть статик

А попробовать?
Re[3]: специализация шаблона - усталая голова форуму покоя не даёт
От: Erop Россия  
Дата: 25.08.14 05:01
Оценка:
Здравствуйте, Molchalnik, Вы писали:

A>>добавь inline или static.

M>К шаблону-то? Думаешь, сработает? А зачем? Шаблоны не требуют инлайна и вряд ли могут быть статик

а разве полная специализация функции -- это шаблон?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: специализация шаблона - усталая голова форуму покоя не даёт
От: ilnar Россия  
Дата: 25.08.14 05:28
Оценка: 3 (1) +1 -1
Здравствуйте, Molchalnik, Вы писали:

M>Прошу прощения, конец дня, работаю без выходных, туплю сильно и прекрасно осознаю, что задаю дурацкий вопрос. Но обычно у меня проблем с шаблонами не возникает, я считаю, что хорошо разбираюсь в них.


функции не специализируются, только перегрузка

namespace some {
template <typename Tn> Tn* CO(Tn *) {return NULL;}
GenlOps* CO(GenlOps*) {return NULL;}
Semaphore* CO(Semaphore*) {return NULL;}
}
Re[2]: специализация шаблона - усталая голова форуму покоя не даёт
От: Constructor  
Дата: 25.08.14 07:18
Оценка:
I>функции не специализируются, только перегрузка

Это-то еще почему? Прекрасно специализируются.
Re[2]: специализация шаблона - усталая голова форуму покоя не даёт
От: uzhas Ниоткуда  
Дата: 25.08.14 07:43
Оценка:
Здравствуйте, ilnar, Вы писали:

I>функции не специализируются, только перегрузка


функции специализируются, но это не рекомендуется делать. желательно использовать перегрузку функций
можно почитать здесь:
http://stackoverflow.com/questions/7108033/template-specialization-vs-function-overloading
http://www.gotw.ca/publications/mill17.htm
http://www.gotw.ca/gotw/049.htm
Re[3]: специализация шаблона - усталая голова форуму покоя не даёт
От: Constructor  
Дата: 25.08.14 08:53
Оценка:
Здравствуйте, uzhas, Вы писали:

U>функции специализируются, но это не рекомендуется делать


Это несколько отлично от

U>функции не специализируются, только перегрузка


Вы не находите?
Re[3]: специализация шаблона - усталая голова форуму покоя не даёт
От: wander  
Дата: 25.08.14 18:43
Оценка:
Здравствуйте, Molchalnik, Вы писали:

A>>добавь inline или static.

M>К шаблону-то? Думаешь, сработает? А зачем? Шаблоны не требуют инлайна и вряд ли могут быть статик

Шаблоны могут требовать инлайн и могут быть статик.

Но тут не шаблон, тут азы про раздельную компиляцию, определение и объявление, и про то, что вообще такое заголовочный файл.
Так что да, поможет. Но сперва азы.
Re[4]: специализация шаблона - усталая голова форуму покоя не даёт
От: uzhas Ниоткуда  
Дата: 25.08.14 19:40
Оценка:
Здравствуйте, Constructor, Вы писали:

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


U>>функции специализируются, но это не рекомендуется делать


C>Это несколько отлично от


U>>функции не специализируются, только перегрузка


C>Вы не находите?


я с вами согласен, только к чему был этот вопрос

по теме добавлю, что для шаблонных функций недопустимы частичные специализации
кину еще одну ссылочку с SO : http://stackoverflow.com/questions/8061456/c-function-template-partial-specialization
Re[4]: специализация шаблона - усталая голова форуму покоя не даёт
От: Molchalnik  
Дата: 26.08.14 11:01
Оценка:
Здравствуйте, wander, Вы писали:

W>Но тут не шаблон, тут азы про раздельную компиляцию, определение и объявление, и про то, что вообще такое заголовочный файл.

W>Так что да, поможет. Но сперва азы.

Нет никаких заголовочных файлов, это миф. Иллюзия, созданная майя. Они просто чудятся. Но при чём тут специализация шаблона функции?
Re[5]: специализация шаблона - усталая голова форуму покоя не даёт
От: wander  
Дата: 31.08.14 10:12
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Но при чём тут специализация шаблона функции?

Неправильный вопрос. Правильный вопрос: при чем тут multiple definition. Правильный ответ — при всем вышеперечисленном. Если кратко: полная специализация функции уже не шаблон -> функция по-умолчанию имеет внешнее связывание -> в С++ раздельная компиляция -> линкер не может выбрать из двух одинаковых имен -> ошибка "multiple definition".

Вот эта фраза:
M> Шаблоны не требуют инлайна и вряд ли могут быть статик
Выдает недостаточно глубокое понимание того, что происходит на этапе компиляции. Посему был совет, между прочим совсем не злой, остановиться и пройтись еще раз по азам. Успехов.
Re[6]: специализация шаблона - усталая голова форуму покоя не даёт
От: Molchalnik  
Дата: 02.09.14 11:26
Оценка:
Здравствуйте, wander, Вы писали:

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


M>>Но при чём тут специализация шаблона функции?

W>Неправильный вопрос. Правильный вопрос: при чем тут multiple definition. Правильный ответ — при всем вышеперечисленном. Если кратко: полная специализация функции уже не шаблон -> функция по-умолчанию имеет внешнее связывание -> в С++ раздельная компиляция -> линкер не может выбрать из двух одинаковых имен -> ошибка "multiple definition".

W>Вот эта фраза:

M>> Шаблоны не требуют инлайна и вряд ли могут быть статик
W>Выдает недостаточно глубокое понимание того, что происходит на этапе компиляции. Посему был совет, между прочим совсем не злой, остановиться и пройтись еще раз по азам. Успехов.

Можно ссылку на стандарт?
Мои проблемы с шаблонами возникают в основном при переходе на gcc
Т.е. или специфика жисиси, или просто он ближе к стандарту

M>> Шаблоны не требуют инлайна и вряд ли могут быть статик

насколько я знаю, компилер сам инлайнит методы, и делает это легко. Статик маркирует функцию как "внутри модуля"
W>Посему был совет, между прочим совсем не злой, остановиться и пройтись еще раз по азам. Успехов.
Когда я учил азы, они были совсем другими, дружище Поэтому знания у меня (имхо) вполне на уровне, но они борланд и mvc -specific. А сейчас в моде стандарт. Вот и приходится удивляться, что годами наработанные схемы перестают работать и переучиваться. Но это хорошо. Нет ничего печальнее кодеров, застрявших в прошлом. Я видел суперпрофи 90х, застрявших в тех временах, и тормозящих целые крупные фирмы ретроградством.
Re[7]: специализация шаблона - усталая голова форуму покоя не даёт
От: wander  
Дата: 04.09.14 06:14
Оценка: 1 (1)
Здравствуйте, Molchalnik, Вы писали:

M>Можно ссылку на стандарт?

Параграфы 3.2 и 3.5 в разделе Basic Concepts.

M>Мои проблемы с шаблонами возникают в основном при переходе на gcc

M>Т.е. или специфика жисиси, или просто он ближе к стандарту

M>насколько я знаю, компилер сам инлайнит методы, и делает это легко. Статик маркирует функцию как "внутри модуля"

Инлайнятся легко только маленькие методы (хотя это тоже вещь интересная, например мой gcc 4.4.2 в одной единице трансляции заинлайнил метод у шаблона, а в другой вставил jmp на него, хотя код и там и там был одинаковый), но речь сейчас не об этом.

Смотри, тут дело в том, что не смотря на то, что в отличие от обычных функций шаблоны допускают множественное определение (так же, как inline-функции), это не значит, что шаблоны по-умолчанию inline. Из похожести поведения не следует, что это одно и то же. Вот пример, который демонстрирует разницу:
  Скрытый текст
//
//other.h
//
#ifndef OTHER_H_INCLUDED
#define OTHER_H_INCLUDED

template <typename T>
class A
{
public:
    void small(); // small function
    void big(); // big function
};

template <typename T>
inline void A<T>::small()
{
    /*small code*/
}

template <typename T>
void A<T>::big()
{
    /*big code*/
}

#endif // OTHER_H_INCLUDED

//
//other.cpp
//
#include "other.h"

extern template class A<int>;

void bar()
{
    A<int> a;

    a.small();

    a.big();
}

//
//main.cpp
//
#include "other.h"

template class A<int>;

int main()
{
    A<int> a;

    a.small();
    a.big();
}

Тут маленькая функция помечена как inline, а большая нет. Если мы уберем inline у маленькой функции, то компилятор (в other.cpp) начнет вызывать ее из другой единицы трансляции, что, собственно, для нее не нужно.
И по поводу static: про linkage упоминалось не зря, шаблонные функции имеют внешнее связывание, так же, как обычные. Поэтому, если функция большая (или компилятор почему-то решил ее не встраивать), то даже без извратов с extern template, компилятор может вызывать ее из другой единицы трансляции, если нам это не нужно, то с помощью static можно сделать функции внутреннее связывание.
Ну и, как уже говорили, на полные специализации не распространяются допуски для шаблонов на множественное определение, потому что это уже не шаблоны. Соответственно, inline, как раз мог бы помочь вернуть этот допуск, если требуется. Хотя я бы предпочел решать твою проблему выносом определения полной специализации в отдельную единицу трансляции (т.к. размещение в заголовочном файле несет те же проблемы, что и для обычных функиций).

M>Когда я учил азы, они были совсем другими, дружище

Ну хорошо. Я тоже не вчера их учил, поэтому тебя понимаю. Другое дело, что по нику гадать тяжело, поэтому не пойми превратно.

M>Поэтому знания у меня (имхо) вполне на уровне, но они борланд и mvc -specific. А сейчас в моде стандарт. Вот и приходится удивляться, что годами наработанные схемы перестают работать и переучиваться. Но это хорошо. Нет ничего печальнее кодеров, застрявших в прошлом. Я видел суперпрофи 90х, застрявших в тех временах, и тормозящих целые крупные фирмы ретроградством.

Согласен.
Re[4]: специализация шаблона - усталая голова форуму покоя не даёт
От: slava_phirsov Россия  
Дата: 04.09.14 14:45
Оценка:
Здравствуйте, flаt, Вы писали:

F>А попробовать?


А оставить в заголовочном файле объявление специализации, а ее определение отправить в приличествующий *.cpp — что мешает?
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[2]: специализация шаблона - усталая голова форуму покоя не даёт
От: Vain Россия google.ru
Дата: 07.09.14 22:49
Оценка:
Здравствуйте, ilnar, Вы писали:

M>>Прошу прощения, конец дня, работаю без выходных, туплю сильно и прекрасно осознаю, что задаю дурацкий вопрос. Но обычно у меня проблем с шаблонами не возникает, я считаю, что хорошо разбираюсь в них.

I>функции не специализируются, только перегрузка
ты путаешь, они частично не специализировались, полностью — можно
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: специализация шаблона - усталая голова форуму покоя не даёт
От: B0FEE664  
Дата: 25.09.14 11:50
Оценка:
Здравствуйте, uzhas, Вы писали:

U>кину еще одну ссылочку с SO : http://stackoverflow.com/questions/8061456/c-function-template-partial-specialization


Это у него там неправильный подход.
Вот как надо:

template <int nMin = 0, int nMax = 5>
int clamp(int n)
{
    return n < nMin ? nMin : n <= nMax ? n : nMax;
}

template <>
int clamp<0, 0>(int n)
{
    return 0;
}

здесь
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.