Имеется параметризованный класс.
Для него написаны параметризованные операторы
сравнения. Естественно, они объявлены друзьями
класса, их код идет ниже описания класса.
Компилятор C++Builder 6.0.
Я тебе не говорил, что функцию шаблон нельзя объявить другом. Я сказал, что другом ты объявляешт не функцию шаблон (в твоем исходном примере). Затем я описал, как можно решить твою проблему. Что непонятно?
template<class T>
class A
{
friend void fun(A);
}
Здесь другом объявлена не функция шаблон. Т.е. для класса A<int> другом будет функция fun(A<int>) и т.д. — их определений-то и нету у тебя. Если б ты, допустим, еще определил друга в классе А (так, как это сделано у тебя) — то это тоже РЕШИТ твою проблему
Of course, the code must be complete enough to compile and link.
L_L>Здесь другом объявлена не функция шаблон. Т.е. для класса A<int> другом будет функция fun(A<int>) и т.д. — их определений-то и нету у тебя. Если б ты, допустим, еще определил друга в классе А (так, как это сделано у тебя) — то это тоже РЕШИТ твою проблему
template<class T>class A
{
friend void fun(A<T>)
{
}
};
Я имел в виду такое.
Of course, the code must be complete enough to compile and link.
А предварительные объявления, как в моем примере, ты делал? Если что-то не компилится, ты б хоть текст сообщений приводил. Такое компилиться должно, если только в BCC нет глюков с друзьями
Of course, the code must be complete enough to compile and link.
Re[3]: Инстанцирование шаблонных функций. Ошибка при линковк
От:
Аноним
Дата:
29.09.03 13:11
Оценка:
L_L>Так если это VC, то тогда да, он такое не любит fun(z<int>) — объявляй тогда указатель на функцию, либо явно инстанцируй
Да, это MSVC 6
так тоже не линкуется
template <typename T>
void z(const T t)
{}
template <typename T>
void f(const T t)
{}
//Instantiate z with the explicitly specified template
//argument ‘int’template void z<int> (int);
int main(int argc, char* argv[])
{
f(z<int>);
return 0;
}
пробовал
(void)(z<int>);
(void*)(z<int>);
(void*)(&z<int>);
void(*pz)(const int) = &(z<int>);
всё равно не помогает, некоторые даже не компилируются.
спасает только
if(0) z<int>(1);
и
int void(*pz)(int)
pz = z<int>;
Откуда растут ноги:
в некоторые места(шаблоны) нужно передавать функторы —
можно передать либо класс, в котором есть operator() или функцию (её адрес).
Всё было нормально до тех пор, пока я не попытался передать туда инстанциированную шаблонную функцию.
Может это потому, что шаблонная функция не может быть параметром шаблона (могу наврать, но что-то подобное есть в стандарте).
Но я ведь передаю туда её конкретный "инстанс".
Это следствие стандарта или просто глюк VC6?
Re[4]: Инстанцирование шаблонных функций. Ошибка при линковк
У вижуала есть еще одна интересная особенность — он позволяет явно инстанцировать несуществующие функции — что и продемонстрировал твой пример. Кроме того, мне кажется, что писать явное инстанцирование получше, чем макросы и if(0)....
Of course, the code must be complete enough to compile and link.
Re[7]: Инстанцирование шаблонных функций. Ошибка при линковк
От:
Аноним
Дата:
29.09.03 14:55
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>У вижуала есть еще одна интересная особенность — он позволяет явно инстанцировать несуществующие функции — что и продемонстрировал твой пример.
Думаю, здесь всё честно — попросили инстанциировать, значит он её сгенерил. Она легла в соответствующий obj файл. Что значит несуществующие?
L_L>Кроме того, мне кажется, что писать явное инстанцирование получше, чем макросы и if(0)....
Эти вызовы разбросаны по всему проекту, и мне не очень хочется вручную вычислять, какие функции и с какими параметрами мне надо инстанциировать. К тому же сам вызов содержится внутри макроса. Проще вставить if(0) { вызов функции } и пусть компилятор потом ищет, на кого ссылались. Вставить в макрос явное инстанциирование нельзя — макрос используется внутри функций и template там писать нельзя.
Единственный минус — пришлось сделать два типа макросов — там где функтор это функция и там где функтор это объект. Придумать для них код, годный и для функции и для объекта и вызывающий инстанциирование функции я не смог.
Данный вариант с предварительным
объявлением операторов привел к положительному
результату, то есть сборка прошла успешо. Но...
Теперь появилась ошибка времени выполнения
"Integer Overflow", за ней другая и программа
кончает свою жизнь. Кроме того в отладчике
после установки точки останова на строку с выражением,
содержащим вызов оператора, отладчик попадает
совсем в другое место текста программы.
Это что, ошибка при генерации кода шаблона
или надо в настройках среды BCB 6 задавать
какой-то параметр.
С уважением Александр.
Re[8]: Инстанцирование шаблонных функций. Ошибка при линковк
А>Думаю, здесь всё честно — попросили инстанциировать, значит он её сгенерил. Она легла в соответствующий obj файл. Что значит несуществующие?
Я имею в виду следующее.
template<class T>
class A
{
void fun(T)const
{
}
};
template void A<int>::fun();
int main()
{
return 0;
}
Of course, the code must be complete enough to compile and link.
E>Данный вариант с предварительным E>объявлением операторов привел к положительному
Естественно, так как это правильная программа. Правда БЦЦ мог бы и не скомпилировать ее по какой-нить причине, например другой вариант
template<class T>
class A
{
template<class T>friend void fun(A<T>);
}
Приводит к Internal Compiler Error — и тут уж похоже ничего не сделаешь
E>Теперь появилась ошибка времени выполнения E>"Integer Overflow", за ней другая и программа E>кончает свою жизнь.
Я так понимаю, что к исходному вопросу про объявление друзей это уже не имеет отношения
Кроме того в отладчике E>после установки точки останова на строку с выражением, E>содержащим вызов оператора, отладчик попадает E>совсем в другое место текста программы.
Опиши подробней. Я БЦЦ воспользовался только чтоб проверить, что он компилирует, а что нет.
Of course, the code must be complete enough to compile and link.