Здравствуйте. Я хочу создать 2 функции с одинаковым именем, но одна должна работать с указателями, другая с обычными данными: Код (Text): template <typename t> int func(t const& value) { return 1; } template <typename t> int func(t const* value) { return 2; } Но такой код всегда вызывает первую функцию.. Код (Text): void main() { int res = func(n); // res = 1 res = func(&n); // res = 1 } Как быть?
Код (Text): template <typename t> int func(t const value) { return 1; } template <typename t> int func(t const* value) { return 2; } что то мне подсказывает что то что написал ты не прокатит. может так. по сути что & что * передаются как ссылки.
Нужно или Код (Text): template <typename t> int func(t * value) { return 2; } или Код (Text): const int n = 0; int res = func(n); // res = 1 res = func(&n); // res = 1
template <typename t> int func(const t& value) { return 1; } template <typename t> int func(const t * value) { return 2; } int res = func<int>(n); // res = 1 res = func<int>(&n); // res = 1
компилятор какой? added: template <typename t> int func(t* value) { return 2; } не заметил пост с решением Velheart
Ещё такой вопрос. Можно как-то различить простые типы (int, char, short, unsigned int, float, double и т.п) с классами и структурами? Я хочу написать несколько реализаций одной функции, типа Код (Text): template <typename t> int func(t const& value) { // если t - класс или структура, то return value.method(); // если t - целочисленный тип или вещественный, то return 1; } template <typename t> int func(t* value) { // если t - класс или структура, то return value->method(); // если t - целочисленный тип или вещественный, то return 2; }
2010 студия на код в нулевом посте выдаёт: Код (Text): const int n = 0; int res = func(n); // res = 1 res = func(&n); // res = 2
С помощью всего доступного арсенала(характеристик, перегрузки, специализации). У Александреску описано, в loki реализовано.
Да, я там неправильно написал. Если писать без конста Код (Text): int n = 0; то Код (Text): int res = func(n); // res = 1 res = func(&n); // res = 1
Ну так это другое дело, смотрите: Код (Text): #include <iostream> template <typename t> int func(t const& value) { std::cout<<typeid(t).name()<<std::endl; return 1; } template <typename t> int func(t const* value) { std::cout<<typeid(t).name()<<std::endl; return 2; } void main() { int n = 0; int res = func(n); // res = 1 res = func(&n); // res = 1 } В данном случае у компилятора есть выбор между указателем на константу и ссылкой на константный указатель и он делает выбор в пользу второго, что по-моему вполне логично. З.Ы. Хотя это скорее логично со стороны компилятора, а не человека. Но такова природа C++. ^)
cupuyc для каждого простого типа перегрузить функцию, шаблон для всего остального. Или наоборот, смотря каких типов будет больше.
ant_man, вот этим гемором я и не хотел заниматься - писать с десяток реализаций. Я сделал is_ariphmetic и написал 2 реализации шаблонного класса: один для is_ariphmetic<> = false, другой - для true. Хотя, тоже не совсем изящно получилось. Лучше, конечно, если бы существовала возможность частичной инициализации шаблонных функций.
cupuyc Код (Text): template <typename t> int func(t const& value, std::false_type) { return 1; } template <typename t> int func(t const* value, std::true_type) { return 2; } template <typename t> int func(t value) { return func(value, std::is_pointer<t>()); }