![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Написал некий тестовый код, куда вбил довольно много элементарных тонкостей С++. Не то чтоб это всё было возможно помнить, но с другой стороны, не помня это, довольно тяжело писать правильный (нетривиальный) темплейтный код. Впрочем, даже и помня, всё равно тяжело.
Задание простое - определить, какая именно специализация функции вызывается (значение типа Т), результаты печати функциями printf а также возможные ошибки компиляции, если они будут.
Класс SayMyName специально устроен так, чтобы его использование генерило ошибку компиляции, в которой бы указывалось значение типа Т. Разумеется, его использование за ошибку компиляции мы считать не будем. Вроде бы были у меня случаи компиляторов, когда подобный трюк давал плохую диагностику, в этом случае можно было просто декларировать, но не имплементировать функции funcByVal и funcByRef, получая уже сообщения линкера, из которых уже можно было попытаться найти значения типа T.
template< class T > class SayMyName
{
// const int say=0; - this is underfined! :-)
};
template < class T > void funcByVal(T) { SayMyName< T >::say; }
template < class T > void funcByRef(T&) { SayMyName< T >::say; }
void test()
{
int i;
const int ci=0;
int &ri=i;
const int &rci=ci;
// what else?
// just 1, literal
//and...
int f();
const int cf();
funcByVal(i);
funcByVal(ci);
funcByVal(ri);
funcByVal(rci);
funcByRef(i);
funcByRef(ci);
funcByRef(ri);
funcByRef(rci);
funcByRef(1);
funcByRef(f());
funcByRef(сf());
// some more fun - do you know arrays? really?
int ar[10];
printf("%d\n", int(&ar)-int(ar));
printf("%d\n", int(1+ar)-int(ar));
printf("%d\n", int(1+&ar)-int(&ar));
funcByVal(ar);
funcByVal(&ar);
funcByRef(ar);
funcByRef(&ar);
funcByVal("test");
funcByVal(&"test");
funcByRef("test");
funcByRef(&"test");
}
дополнительное задание: как будет работать предыдущий пример, если определить следующие две функции, какие из них когда будут вызываться и с каким значением типа?
template < class T > void funcByRef(T&) { SayMyName< T >::say; }
template < class T > void funcByRef(const T&) { SayMyName< T >::say; }
Задание простое - определить, какая именно специализация функции вызывается (значение типа Т), результаты печати функциями printf а также возможные ошибки компиляции, если они будут.
Класс SayMyName специально устроен так, чтобы его использование генерило ошибку компиляции, в которой бы указывалось значение типа Т. Разумеется, его использование за ошибку компиляции мы считать не будем. Вроде бы были у меня случаи компиляторов, когда подобный трюк давал плохую диагностику, в этом случае можно было просто декларировать, но не имплементировать функции funcByVal и funcByRef, получая уже сообщения линкера, из которых уже можно было попытаться найти значения типа T.
template< class T > class SayMyName
{
// const int say=0; - this is underfined! :-)
};
template < class T > void funcByVal(T) { SayMyName< T >::say; }
template < class T > void funcByRef(T&) { SayMyName< T >::say; }
void test()
{
int i;
const int ci=0;
int &ri=i;
const int &rci=ci;
// what else?
// just 1, literal
//and...
int f();
const int cf();
funcByVal(i);
funcByVal(ci);
funcByVal(ri);
funcByVal(rci);
funcByRef(i);
funcByRef(ci);
funcByRef(ri);
funcByRef(rci);
funcByRef(1);
funcByRef(f());
funcByRef(сf());
// some more fun - do you know arrays? really?
int ar[10];
printf("%d\n", int(&ar)-int(ar));
printf("%d\n", int(1+ar)-int(ar));
printf("%d\n", int(1+&ar)-int(&ar));
funcByVal(ar);
funcByVal(&ar);
funcByRef(ar);
funcByRef(&ar);
funcByVal("test");
funcByVal(&"test");
funcByRef("test");
funcByRef(&"test");
}
дополнительное задание: как будет работать предыдущий пример, если определить следующие две функции, какие из них когда будут вызываться и с каким значением типа?
template < class T > void funcByRef(T&) { SayMyName< T >::say; }
template < class T > void funcByRef(const T&) { SayMyName< T >::say; }