Здравствуйте, Аноним, Вы писали:
А>Есть класс свойств типа.
Это упражнение или велосипед? Если велосипед, то стоит посмотреть на boost::mpl, а если упражнение, то будем разбираться.
А>Неправильно определяются типы при передаче в функцию.
А>А>template<typename T>
А>void funcBy(T)
А>{
А>std::cout<<"parameter is ref: "<<((client::A_TypeTraits<T>::isRef)?"true":"false")<<std::endl;
А>std::cout<<"parameter is Cref: "<<((client::A_TypeTraits<T>::isCRef)?"true":"false")<<std::endl;
А>std::cout<<"parameter is by val: "<<((client::A_TypeTraits<T>::isFundamental)?"true":"false")<<std::endl<<std::endl;
А>}
А>A a;
А>A& ra = a;
А> funcBy(client::A_TypeTraits<int>::ParameterType());
А> funcBy(client::A_TypeTraits<A>::ParameterType(a));
А> funcBy(client::A_TypeTraits<A&>::ParameterType(ra));
А>
А>Только первый вызов выводит false false true. Остальные 2 выводят только false.
Дело в том, что тип T у функции выводится. Поскольку funcBy принимает "нечто типа T" по значению, то, что бы ей на вход ни подсунули, первым делом произойдёт неявное приведение к rvalue. А если lvalue->rvalue невозможно из-за приватного конструктора копирования, то будет ошибка компиляции.
Поэтому в первой строке T=int, во второй и третьей T=A. Даже если подсунуть туда const A, — всё равно const lvalue -> rvalue потеряет константность.
Кстати сказать, у переменной a и ссылки на ней ra тип один и тот же — это A, а вовсе не A&.
Если же явно указывать параметр funcBy<int>, funcBy<A>, funcBy<A&>, funcBy<const A&> — то вывод будет ожидаемо разный.