Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
07.11.2017, 10:48  [ТС]
Студворк — интернет-сервис помощи студентам
Всем привет.

Есть такой код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <type_traits>
#include <utility>
using namespace std;
 
class empty_type {};
 
template<typename T, typename A = empty_type>
struct has_foo : std::false_type {};
 
template<class T>
struct has_foo<T, decltype(std::declval<T>().foo(int()))> : std::true_type {};
 
struct bad_foo_1
{
    void foo(int);
};
 
struct bad_foo_2
{
    int foo(int);
};
 
struct good_foo
{
    empty_type foo(int);
};
 
int main()
{
    std::cerr << std::boolalpha;
    std::cerr << has_foo<int>::value << std::endl;
    std::cerr << has_foo<bad_foo_2>::value << std::endl;
    std::cerr << has_foo<bad_foo_1>::value << std::endl;
    std::cerr << has_foo<good_foo>::value << std::endl;
 
    return 0;
}
Выдает:
false
false
false
true

Вопрос: почему вывод не
false
true
true
true ?
0
 Аватар для animefan
119 / 9 / 2
Регистрация: 06.09.2017
Сообщений: 82
07.11.2017, 12:43
Цитата Сообщение от stzer Посмотреть сообщение
Вопрос: почему вывод не
Потому что если в частичной специализации специализированные типы отличаются от типов-аргументов по-умолчанию базового шаблона, то выбирается базовый, а не специализированный шаблон. Т.е. пока decltype(std::declval<T>().foo(int())) не совпадает с empty_type, выбирается шаблон из 8-9 строки.

См. https://stackoverflow.com/a/18701381
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.11.2017, 13:12
Цитата Сообщение от stzer Посмотреть сообщение
Вопрос: почему вывод не
false
true
true
true ?

как вообще определяется, какую специализацию выбрать?

правило звучит:
специализации должны уточнять параметры базового шаблона.

это значит, что фактические параметры шаблона
должны подходить для базового шаблона,
но для специализации они подходят ещё лучше.


теперь рассмотрим процесс инстанцирования по шагам.
итак, есть два шаблона:

C++
1
2
3
4
5
template<typename T, typename A = void>
struct has_foo : std::false_type {};
 
template<class T>
struct has_foo<T, decltype(std::declval<T>().foo(int()))> : std::true_type {};
инстанцируем так:

C++
1
2
3
4
5
struct good { void foo(int); };
 
...
 
std::cout << has_foo<good>::value << std::endl;

сначала компилятор проверяет соответствие базовому шаблону:
has_foo<good, void>,
где второй параметр вывелся по умолчанию.

затем компилятор рассматривает на предмет того,
есть ли специализация,
для которой "общие параметры" подходят лучше?

C++
1
2
3
template<class T>
struct has_foo<T, decltype(std::declval<T>().foo(int()))>  // можно инстанцировать как has_foo<good, void>
    : std::true_type {};
специализация подошла.
правило гласит:
при обнаружении подходящей специализации,
выбирается она.
а не базовый шаблон.

--------------------------------------------------------------------------

теперь рассмотрим второй случай:

C++
1
struct bad  { int foo(int) ; };
сначала компилятор проверяет соответствие базовому шаблону:
has_foo<bad, void>,
где второй параметр вывелся по умолчанию.

затем рассматривает на предмет того,
есть ли специализация,
для которой "общие параметры" подходят лучше?

C++
1
2
3
template<class T>
struct has_foo<T, decltype(std::declval<T>().foo(int()))>  // нельзя инстанцировать как has_foo<bad, void>
    : std::true_type {};
специализация провалилась.

правило гласит:
если ни одна из специализаций не подошла,
тогда выбран должен быть главный шаблон.
0
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
07.11.2017, 13:28  [ТС]
Оууу. Вроде дошло, почему во втором случае специализация провалилась. Всем спасибо
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.11.2017, 13:30
Цитата Сообщение от stzer Посмотреть сообщение
Оууу. Вроде дошло, почему во втором случае специализация провалилась. Всем спасибо
если упростить ваш пример:

http://rextester.com/BUUI59285

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
// общий случай: когда T - char
template<class T, bool is_char = ::std::is_same<T, char>::value>
struct sample
{
    enum { value = 1 };
};
 
// специализация сработает, когда T - не char
template<class T>
struct sample<T, false>
{
    enum { value = 0 };
};
 
 
int main()
{
    // второй параметр выведется как false
    // sample<int, false> подходит к специализации
    std::cout << "is char?  " << sample<int>::value  << '\n'; 
    
    // второй параметр выведется как true
    // sample<char, true> подходит только базовому шаблону
    std::cout << "is char?  " << sample<char>::value << '\n'; 
}
0
Ответ Создать тему
Новые блоги и статьи
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru