массив, ссылка или указатель?
От: collider  
Дата: 03.02.17 19:38
Оценка:
Как сделать, чтобы примерно такой код компилировался?

template<class T,size_t sz>
inline void reset(T(&x)[sz] )
{

}

template<class T>
inline void reset(T* x)
{

}

template<class T>
inline void reset(T& x)
{

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

    int nRetCode = 0;
    
    char mass[10];
    char *pmass=mass;


    reset(mass);// error C2668: 'reset': ambiguous call to overloaded function
    reset(pmass);
    reset(nRetCode);    
    return nRetCode;
}
Отредактировано 06.02.2017 12:19 Кодт . Предыдущая версия .
Re: массив, ссылка или указатель?
От: kov_serg Россия  
Дата: 03.02.17 19:50
Оценка: -2
Здравствуйте, collider, Вы писали:

C>Как сделать, чтобы примерно такой код компилировался?


C>void reset(T(&x)[sz] )

поменяйте на
void reset(T x[sz])
Re: массив, ссылка или указатель?
От: Conr Россия  
Дата: 03.02.17 19:52
Оценка: +3 -1
Здравствуйте, collider, Вы писали:

C>Как сделать, чтобы примерно такой код компилировался?

#include <cstddef>
#include <type_traits>
#include <iostream>
 
template<class T, std::size_t sz>
inline void reset(T(&x)[sz] )
{
    std::cout << "array\n";
}
 
template<class T>
inline typename std::enable_if<std::is_pointer<T>::value, void>::type reset(T x)
{
    std::cout << "pointer\n";
}
 
template<class T>
inline typename std::enable_if<!std::is_pointer<T>::value, void>::type reset(T& x)
{
    std::cout << "reference\n";
}
 
int main(int argc, const char* argv[], const char* envp[])
{
    int nRetCode = 0;
 
    char mass[10];
    char *pmass=mass;
 
 
    reset(mass);
    reset(pmass);
    reset(nRetCode);    
    return nRetCode;
}


Пример: http://ideone.com/bFotSR
http://files.rsdn.org/8859/82254.gif
Re: массив, ссылка или указатель?
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.02.17 20:24
Оценка: 68 (1)
C>Как сделать, чтобы примерно такой код компилировался?

...

template<class T>
inline void reset(T* const & x)

http://ideone.com/T9CoNj

А еще можно посмотреть boost::range, там это уже сделано.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: массив, ссылка или указатель?
От: rg45 СССР  
Дата: 05.02.17 12:08
Оценка:
Здравствуйте, kov_serg, Вы писали:

C>>Как сделать, чтобы примерно такой код компилировался?


C>>void reset(T(&x)[sz] )

_>поменяйте на
_>void reset(T x[sz])

Только вот компилироваться код станет только лишь потому, что эта функция никогда не выиграет конкурс на подстановку. Просто потому, что шаблонный параметр sz не может быть выведен автоматически — просто потому, что параметры-массивы автоматом интерпретируются компилятором как указатели. И все по стандарту.
--
Соседи приходят — им слышится стук копыт
Re: массив, ссылка или указатель?
От: rg45 СССР  
Дата: 05.02.17 12:59
Оценка: 68 (1)
Здравствуйте, collider, Вы писали:

C>Как сделать, чтобы примерно такой код компилировался?


Решения можно придумать разные, в зависимости от ситуации. Классика жанра — реализация одной шаблонной функции через серию специализаций шаблонного класса-имплеиентации.

Или SFINAE:

http://ideone.com/2dKajZ

#include <iostream>
#include <utility>

template<class T>
std::enable_if_t<std::is_fundamental<std::remove_reference_t<T>>::value> reset(T&&)
{
    std::cout << 1 << std::endl;
}

template<class T>
std::enable_if_t<std::is_pointer<std::remove_reference_t<T>>::value> reset(T&&)
{
    std::cout << 2 << std::endl;
}

template<class T>
std::enable_if_t<std::is_array<std::remove_reference_t<T>>::value> reset(T&&)
{
    std::cout << 3 << std::endl;
}

int main()
{

    int nRetCode = 0;
    
    char mass[10];
    char *pmass=mass;

    reset(mass);
    reset(pmass);
    reset(nRetCode);    
}
--
Соседи приходят — им слышится стук копыт
Re: массив, ссылка или указатель?
От: VTT http://vtt.to
Дата: 05.02.17 14:40
Оценка:
У вашего кода две проблемы:
1) Объявлены три разных шаблона методов, соответственно если несколько из них подходят, то получается ошибка с двумя перегруженными методами, а не выбор подходящего.
2) ссылка на указатель не разбирается

http://ideone.com/EpxHub

#include <iostream>
#include <cstddef> // for size_t

template< typename T > class
reset_impl_t;

template< typename T, ::std::size_t sz > class
reset_impl_t< T(&)[sz] >
{
    public: static void
    reset(T(&x)[sz])
    {
        (void) x; // not used
        ::std::cout << "array" << ::std::endl;
    }
};

template< typename T > class
reset_impl_t< T * >
{
    public: static void
    reset(T * x)
    {
        (void) x; // not used
        ::std::cout << "pointer" << ::std::endl;
    }
};

template< typename T > class
reset_impl_t< T * & >
{
    public: static void
    reset(T * x)
    {
        return(reset_impl_t< T * >::reset(x));
    }
};

template< typename T > class
reset_impl_t< T & >
{
    public: static void
    reset(T & x)
    {
        (void) x; // not used
        ::std::cout << "reference" << ::std::endl;
    }
};

template< typename T >  void
reset(T && x)
{
    return(reset_impl_t< T >::reset(x));
}

int main()
{
    int nRetCode = 0;
    
    char mass[10];
    char * pmass = mass;
    
    reset(mass);
    reset(pmass);
    reset(nRetCode);  
    return 0;
}
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: массив, ссылка или указатель?
От: Andrew S Россия http://alchemy-lab.com
Дата: 05.02.17 17:34
Оценка:
C>>Как сделать, чтобы примерно такой код компилировался?

R>Решения можно придумать разные, в зависимости от ситуации. Классика жанра — реализация одной шаблонной функции через серию специализаций шаблонного класса-имплеиентации.


R>Или SFINAE:


R>http://ideone.com/2dKajZ


Никогда не понимал желания сделать простую задачу сложным способом
Все можно сделать на обычных перегрузках функций:
http://rsdn.org/forum/cpp/6687345.1
Автор: Andrew S
Дата: 03.02.17
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: массив, ссылка или указатель?
От: night beast СССР  
Дата: 05.02.17 17:47
Оценка: +3
Здравствуйте, Andrew S, Вы писали:

R>>Или SFINAE:


R>>http://ideone.com/2dKajZ


AS>Никогда не понимал желания сделать простую задачу сложным способом

AS>Все можно сделать на обычных перегрузках функций:
AS>http://rsdn.org/forum/cpp/6687345.1
Автор: Andrew S
Дата: 03.02.17


я, конечно, извиняюсь, но ты вывод своей программы смотрел?
Re[3]: массив, ссылка или указатель?
От: rg45 СССР  
Дата: 05.02.17 22:18
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Никогда не понимал желания сделать простую задачу сложным способом

AS>Все можно сделать на обычных перегрузках функций:

А если внимательно почитать стартовое сообщение:

Как сделать, чтобы примерно такой код компилировался?


то "примерно такой", имхо, следует понимать не иначе как "такой, когда обычные перегрузки не работают". Я, по крайней мере, именно такую трактовку выбрал в качестве отправной точки.
--
Соседи приходят — им слышится стук копыт
Отредактировано 06.02.2017 2:00 rg45 . Предыдущая версия .
Re[4]: массив, ссылка или указатель?
От: Andrew S Россия http://alchemy-lab.com
Дата: 06.02.17 23:18
Оценка:
R>>>Или SFINAE:

R>>>http://ideone.com/2dKajZ


AS>>Никогда не понимал желания сделать простую задачу сложным способом

AS>>Все можно сделать на обычных перегрузках функций:
AS>>http://rsdn.org/forum/cpp/6687345.1
Автор: Andrew S
Дата: 03.02.17


NB>я, конечно, извиняюсь, но ты вывод своей программы смотрел?


Не вопрос — уберите const или добавьте в другие перегрузки, смотря от того, что надо. Судя по сигнатурам, надо убрать. В целом, идея иметь именно такие перегрузки для меня сомнительна.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: массив, ссылка или указатель?
От: Andrew S Россия http://alchemy-lab.com
Дата: 06.02.17 23:26
Оценка:
AS>>Никогда не понимал желания сделать простую задачу сложным способом
AS>>Все можно сделать на обычных перегрузках функций:

R>А если внимательно почитать стартовое сообщение:


R>

R>Как сделать, чтобы примерно такой код компилировался?


R>то "примерно такой", имхо, следует понимать не иначе как "такой, когда обычные перегрузки не работают". Я, по крайней мере, именно такую трактовку выбрал в качестве отправной точки.


Судя по приведенному коду у человека стандартная задача — дискриминировать указатель от массива. Лучше, чем в буст-рендже, я пока решения не видел. Навороты типа SFINAE для решения этой задачи не нужны.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: массив, ссылка или указатель?
От: rg45 СССР  
Дата: 06.02.17 23:40
Оценка: +1
Здравствуйте, Andrew S, Вы писали:

AS>Не вопрос — уберите const или добавьте в другие перегрузки, смотря от того, что надо. Судя по сигнатурам, надо убрать.


То есть, указатель можно будет передать только по неконстантной ссылке? Очень удобно, спасибо.

AS>В целом, идея иметь именно такие перегрузки для меня сомнительна.


А как же буст-рендж? Там же эта задача зачем-то решается, как ты утверждаешь?
--
Соседи приходят — им слышится стук копыт
Отредактировано 07.02.2017 0:45 rg45 . Предыдущая версия . Еще …
Отредактировано 07.02.2017 0:38 rg45 . Предыдущая версия .
Re[5]: массив, ссылка или указатель?
От: rg45 СССР  
Дата: 07.02.17 00:20
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Судя по приведенному коду у человека стандартная задача — дискриминировать указатель от массива. Лучше, чем в буст-рендже, я пока решения не видел. Навороты типа SFINAE для решения этой задачи не нужны.


Ну так ты доведи сперва свое решение до рабочего состояния, а потом уже делай заключения. И, скажу сразу, необходимость передачи указателя по неконстантной ссылке — решение так себе.

И, кстати, что-то не припоминаю я в boost::range места, где требуется решение такой задачи. Там либо указателей будет пара (begin, end), либо разница между указателем и массивом несущественна. Не назовешь имя класса?
--
Соседи приходят — им слышится стук копыт
Отредактировано 07.02.2017 0:22 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.