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

C++

Войти
Регистрация
Восстановить пароль
 
hoggy
6167 / 2533 / 444
Регистрация: 15.11.2014
Сообщений: 5,601
Завершенные тесты: 1
#1

Во время компиляции определить, является ли тип полным - C++

24.02.2015, 01:56. Просмотров 401. Ответов 5
Метки нет (Все метки)

Доброго времени суток.

Это уже моя далеко не первая попытка создать детектор неполных типов.

Требуется кросс-платформа: сl/mingw/gcc/clang

Моя последняя самая успешная модель не проходит всех тестов.
Она не в состоянии однозначно определить полный ли тип, или не полный,
и имеет на выходе 3 ответа: да, нет, не знаю.

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

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

Ниже представленный код - ещё одна из попыток.
Но возникла непредвиденная проблема.

Мне не понятно, почему этот код вообще скомпилировался???????

http://rextester.com/TJSW25522


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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <type_traits>
 
//Здесь используется модель класса "IsValidExpression"
//Ссылка на первоисточник, и большое спасибо автору за идею:
//http://habrahabr.ru/post/112239/
 
//Примечание: авторский код не безупречен
//содержит технические ошибки, и фейлит многие тесты
 
#define SHECK_VALID_EXPRESSION( dNAME, dEXPRESSION ) \
template< class T > class dNAME                      \
{                                                    \
    struct no{};                                     \
    template< class U >                              \
        static decltype( dEXPRESSION )               \
            test( void* );                           \
    template< class U >                              \
        static no test( ... );                       \
    typedef decltype( test<T>(nullptr) )             \
        result;                                      \
public:                                              \
    enum { value =                                   \
        !std::is_same<no, result>::value };          \
};
 
 
#include <iostream>
#include <utility>
 
struct nocomplete;
struct complete{};
 
typedef std::pair<double, nocomplete>
    pair_nocomplete;
 
typedef std::pair<int, complete>
    pair_complete;
 
 
//-----------------------------------------------
template<class T> void fake(T);
SHECK_VALID_EXPRESSION( IsComplete, fake(U()) );
//-----------------------------------------------
 
int main()
{
    std::cout<<"WELLCOME TO EXAMPLE APPLICATION!\n";
    
    //электроны изменяют своё поведение в зависимости от того, 
    //наблюдает ли кто за ними
    
    std::cout<<"is complete 'nocomplete' ? (must be 0) - "
        << IsComplete<nocomplete>::value<<'\n';
 
    std::cout<<"is complete 'complete' ? (must be 1) - "
        << IsComplete<complete>::value<<'\n';
 
    // Ошибка: "эффект электрона". 
    // Если закомментировать отладочный вывод для pair_nocomplete, 
    // то поведение изменится и станет корректным
    
    std::cout<<"is complete 'pair_nocomplete' ? (must be 0) - "
        << IsComplete<pair_nocomplete>::value<<'\n';
 
    std::cout<<"is complete 'pair_complete' ? (must be 1) - "
        << IsComplete<pair_complete>::value<<'\n';
        
    
    // не полный тип не может быть создан.
    // такое странное поведение наблюдается 
    // только на компиляторах вижал студии
    
    pair_nocomplete pr;  //<--- what the fuck ???????
    pr.second = 20;      
 
    std::cout<<"first = "  << pr.first  <<'\n'; 
    std::cout<<"second = " << pr.second <<'\n'; 
    
    // тип second почему то интерпритируется, как тип int
    // если расскоментировать, получим ошибку:
    // error C2062: type 'int' unexpected
    //std::cout<<"type of second = " << decltype(pr.second).name() <<'\n'; 
    
    //Предварительное заключение:
    //  каким то образом, инстанцирование IsComplete<pair_nocomplete>::value
    //  приводит к сбою в работе компилятора.
    
}
Кто нибудь может объяснить, что за чертовщина с этим кодом творится?
И как это лечить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.02.2015, 01:56     Во время компиляции определить, является ли тип полным
Посмотрите здесь:

C++ Дано натуральное число n. Выяснить, является ли оно полным квадратом.Определить функ-цию, позволяющую распознавать полные квадраты
Ошибка во время компиляции C++
Шаблоны странная ошибка во время компиляции C++
Visual C++ Тип компиляции Release
Определить, является ли дерево почти полным C++
C++ Дано натуральное число n. Выяснить, является ли оно полным квадратом
Сравнение типов во время компиляции C++
Сумма во время компиляции, boost::mpl Boost C++
C++ Builder Builder зависает во время компиляции
C++ Идентификация типа во время компиляции
Возникают непонятные ошибки во время компиляции кода C++
Ошибки во время компиляции программы C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
schdub
2935 / 1279 / 237
Регистрация: 19.01.2009
Сообщений: 3,344
Завершенные тесты: 1
24.02.2015, 14:47     Во время компиляции определить, является ли тип полным #2
hoggy, под CL почему компилируется не знаю. Копилировал под GCC 4.8. Если закомментировать строки ниже 73, то компилятор спотыкается на вызове:
C++
1
IsComplete<pair_nocomplete>::value
Код
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘struct std::pair<double, nocomplete>’:
a.cpp:41:1:   required by substitution of ‘template<class U> static decltype (fake(U())) IsComplete<T>::test(void*) [with U = U; T = std::pair<double, nocomplete>] [with U = std::pair<double, nocomplete>]’
a.cpp:41:1:   required from ‘class IsComplete<std::pair<double, nocomplete> >’
a.cpp:62:39:   required from here
/usr/include/c++/4.8/bits/stl_pair.h:102:11: error: ‘std::pair<_T1, _T2>::second’ has incomplete type
       _T2 second;                /// @c second is a copy of the second object
           ^
a.cpp:30:8: error: forward declaration of ‘struct nocomplete’
 struct nocomplete;
        ^
Решить эту проблему можно специализировав шаблонный класс IsCompete для std :: pair<T1, T2> и проверив полные ли типы T1 и T2:

C++
1
2
3
4
template <class T1, class T2> class IsComplete< std::pair<T1, T2> > {
public:
    enum { value = IsComplete<T1>::value && IsComplete<T2>::value };
};
Если хочется гарантированно избежать проблем с компиляцией, то же самое нужно сделать для Т1, Т2 и всех их вложенных типов.

Код
WELLCOME TO EXAMPLE APPLICATION!
is complete 'nocomplete' ? (must be 0) - 0
is complete 'complete' ? (must be 1) - 1
is complete 'pair_nocomplete' ? (must be 0) - 0
is complete 'pair_complete' ? (must be 1) - 1
Если раскомментировать строки ниже 73 включительно, то будет ошибка компиляции, из-за не полного типа nocomplete.
hoggy
6167 / 2533 / 444
Регистрация: 15.11.2014
Сообщений: 5,601
Завершенные тесты: 1
24.02.2015, 15:38  [ТС]     Во время компиляции определить, является ли тип полным #3
Цитата Сообщение от schdub Посмотреть сообщение
Копилировал под GCC 4.8. Если закомментировать строки ниже 73,
Вероятно вы не заметили эти надписи:

Цитата Сообщение от hoggy Посмотреть сообщение
Требуется кросс-платформа: сl/mingw/gcc/clang
Цитата Сообщение от hoggy Посмотреть сообщение
// такое странное поведение наблюдается
* * // только на компиляторах вижал студии
Очевидно, что я собирал код на множестве компиляторов.
И очевидно, что проблема именно с компиляторами вижал студии.
О gcc сейчас речь вообще не идет.

Цитата Сообщение от schdub Посмотреть сообщение
Решить эту проблему можно специализировав шаблонный класс IsCompete для std :: pair<T1, T2> и проверив полные ли типы T1 и T2:
Это - не есть решение проблемы.

Во-первых, делать специализации под все возможное и невозможное множество возможных типов - контрпродуктивно, и контрэффективно.

А во-вторых:

Мета-функция должна уметь работать с любыми типами.
И с обычными, и с продуктами шаблона.

Но тот факт, что в параметрах шаблона фигурируют не полные типы ещё не означает,
что сам агрегат - так же не полный.

пример:

C++
1
2
3
4
5
6
7
8
9
template<class T1, class T2> 
struct Pair{};
 
...
 
struct nocomplete;
 
typedef Pair<int, nocomplete>
    pair_complete;   //<---- будет полным типом независимо от параметров шаблона
Таким образом, даже если я и проверю типы которым был инстанцирован шаблон,
эта информация не поможет мне 100% установить истину.

Выше я писал:

Цитата Сообщение от hoggy Посмотреть сообщение
Моя последняя самая успешная модель не проходит всех тестов.
Она не в состоянии однозначно определить полный ли тип, или не полный,
и имеет на выходе 3 ответа: да, нет, не знаю.
Теперь вы наверное понимаете принцип её действия,
и что означает её странный ответ "я не знаю".

1. если тип - не продукт шаблона, и он полный, ответ: да.
2. если тип - не продукт шаблона, и он не полный, ответ: нет.
3. если тип - продукт шаблона, но всего его параметры полные, ответ - да.
4. если тип - продукт шаблона, но хотя бы один из его параметров не полный, ответ - не знаю.
Пока что мне не удалось найти способ, как однозначно определить:
так полный тип, или не полный?

И ни одна из виденных мною моделей не проходит 4й тест.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
25.02.2015, 10:24     Во время компиляции определить, является ли тип полным #4
hoggy, Оригинальный баг... Судя по всему ваш вывод верен, но по какой причине такое происходит - нужно обращаться к разработчикам MSVC. Предлагаю написать им в багтрекер.
hoggy
6167 / 2533 / 444
Регистрация: 15.11.2014
Сообщений: 5,601
Завершенные тесты: 1
25.02.2015, 13:08  [ТС]     Во время компиляции определить, является ли тип полным #5
Цитата Сообщение от ForEveR Посмотреть сообщение
Предлагаю написать им в багтрекер.
уже даже ответ получил.
сказали спасибо и пообещали разобраться, что за канитель.
hoggy
6167 / 2533 / 444
Регистрация: 15.11.2014
Сообщений: 5,601
Завершенные тесты: 1
03.03.2015, 22:35  [ТС]     Во время компиляции определить, является ли тип полным #6
Получил ответ от майкрософт:
Hi: this issue has been fixed: the fix will be included in a future release of Visual C++.
Yandex
Объявления
03.03.2015, 22:35     Во время компиляции определить, является ли тип полным
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru