Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Выбор шаблонного варианта для аргумента-массива - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Поток не сигнализирует событием о своем окончании http://www.cyberforum.ru/cpp/thread1272738.html
Всем привет, нужна помощь задача такая. Есть метод у меня (mnThread) который постоянно поставляет данные, процедура (get_data) эти данные получает. Как только данные получены я устанавливаю событие и...
C++ Не могу понять как исправить ошибку #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1... http://www.cyberforum.ru/cpp/thread1272081.html
Помогите построить факториал в MFC C++
Помогите построить факториал в MFC. Целый день капаюсь в уроках, но так ничего не вышло Добавлено через 2 часа 59 минут делаю по примеру...
C++ Как "засунуть" классы в .dll ?
Добрый вечер! У меня имеется классовая иерархия, базовый класс сотрудник, наследники программист, экономист, электронщик и т.п. Сделал базу данных с помощью (vector.h) , и в main заполняю БД, и потом...
C++ Информация по Button, Panel, Label, TextBox в VS2010 http://www.cyberforum.ru/cpp/thread1270298.html
Среда visual c++ 2010 для работы с графическим интерфейсом. Компоненты среды программирования(свойства,события,методы,пример использования) Button, Panel, Label, TextBox. Заранее спасибо за ответ.
C++ Уничтожение файлов и папок, без возможности восстановления Здравствуйте! Собственно это моё задание "Написать windows-приложение для гарантированного удаления файлов(каталогов) без возможности восстановления специализированным ПО". Нашла на википедии... подробнее

Показать сообщение отдельно
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
11.10.2014, 03:05
Цитата Сообщение от Tulosba Посмотреть сообщение
Почему вызывается версия с указателем, а не с ссылкой!?
Если по-простому и на пальцах, то потому что T недостаточно квалифицирован для подстановки. В то время как перегрузка с указателем обеспечивает array-to-pointer conversion, которая одного ранга (Exact Match) с отсутствием какой-либо конверсии, а значит более предпочтительна (см. таблицу в 13.3.3.1.1).
Когда ты добавляешь const к варианту с указателем, то получаешь дополнительно qualification conversion. Перегрузка, требующая конверсии, теряет приоритет перед вариантом со ссылкой.
Чтобы получить нужное тебе поведение, надо в варианте со ссылкой квалифицировать T достаточным образом (тип массива в С++ представляет собой комбинацию типа и размерности):
C++
1
2
3
4
5
6
7
8
9
template <class T>
void func( T * t) {
    std::cout << "*" << sizeof(t) << std::endl;
}
 
template <class T>
void func( T (& t)[10]) {
    std::cout << "&" << sizeof(t) << std::endl;
}
Итого получаем ошибку неоднозначности, теперь перегрузки равны в глазах компилятора. Исправить это можно только вынеся размерность в аргумент шаблона, чтобы вариант начал рассматриваться исходя из подстановки, а не на общих основаниях.
C++
1
2
3
4
template <class T, size_t N>
void func( T (& t)[N]) {
    std::cout << "&" << sizeof(t) << std::endl;
}
Цитата Сообщение от IGPIGP Посмотреть сообщение
Туда где ожидается ссылка на тип можно передать переменную типа, но не указатель же?
Дело в том, что изначально массив не указатель и требует array-to-pointer conversion при передаче, так что вариант с T & может подойти, T разрешится в ссылку на массив. Но массив сложный тип и квалификации T недостаточно для выбора в нашем случае. В то время как преобразование к указателю имеет высокий приоритет, наравне с отсутствием преобразования.

Добавлено через 22 минуты
Как-то я главное не подчеркнул:
В данном случае, с использованием шаблонов помимо правил собственно перегрузки еще вступает в силу параграф 14.8.2. Т.е. сначала определяется, скажем так, степень выводимости шаблона (это не термин, если что), а потом уже правила перегрузки, поэтому-то и влияет так сильно уровень квалификации T. Компилятору не нужно выводить размерность массива, если мы ее указали явно. А в варианте с обычной ссылкой нужно вывести в T еще и размерность массива, поэтому наиболее простым вариантом остается array-to-pointer конвертация, которая, как я уже сказал, идентична по рангу отсутствию конвертации.
10
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru