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

C++

Войти
Регистрация
Восстановить пароль
 
hoggy
6703 / 2885 / 494
Регистрация: 15.11.2014
Сообщений: 6,485
Завершенные тесты: 1
#1

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

24.02.2015, 01:56. Просмотров 433. Ответов 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
    //  приводит к сбою в работе компилятора.
    
}
Кто нибудь может объяснить, что за чертовщина с этим кодом творится?
И как это лечить?
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.02.2015, 01:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Во время компиляции определить, является ли тип полным (C++):

Тип компиляции Release - Visual C++
При изменении типа компиляции с Debug на Release возникает куча ошибок..Из-за чего это? Все ошибки связаны с преобразованием. Например...

Определить, является ли дерево почти полным - C++
Здравствуйте, подскажите пожалуйста, как произвести проверку является ли дерево почти полным?

Дано натуральное число n. Выяснить, является ли оно полным квадратом.Определить функ-цию, позволяющую распознавать полные квадраты - C++
Вот пока что сделал, дальше домозговать не могу. #include &quot;stdafx.h&quot; #include &quot;math.h&quot; #include &lt;iostream&gt; using namespace std; ...

Дано натуральное число n. Выяснить, является ли оно полным квадратом - C++
Дано натуральное число n. Выяснить, является ли оно полным квадратом. Определить функцию, позволяющую распознавать полные квадраты. C++

Выяснить, является ли заданное число полным квадратом (используя функцию) - C++
#include &lt;stdio.h&gt; int n, i; for(i=1; i&lt; sqrt(n)+1; i++) { if (n==i*i) { cout &lt;&lt; &quot;Kvadra&quot;; return (1); } return 0; } ...

Ошибка во время компиляции - C++
Выбивает ошибку:&quot;Run-Time Check Failure #3 - The variable 'n' is being used without being defined.&quot; Код:#include &quot;stdafx.h&quot; #include...

5
schdub
2959 / 1304 / 239
Регистрация: 19.01.2009
Сообщений: 3,424
Завершенные тесты: 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.
0
hoggy
6703 / 2885 / 494
Регистрация: 15.11.2014
Сообщений: 6,485
Завершенные тесты: 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й тест.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
25.02.2015, 10:24 #4
hoggy, Оригинальный баг... Судя по всему ваш вывод верен, но по какой причине такое происходит - нужно обращаться к разработчикам MSVC. Предлагаю написать им в багтрекер.
0
hoggy
6703 / 2885 / 494
Регистрация: 15.11.2014
Сообщений: 6,485
Завершенные тесты: 1
25.02.2015, 13:08  [ТС] #5
Цитата Сообщение от ForEveR Посмотреть сообщение
Предлагаю написать им в багтрекер.
уже даже ответ получил.
сказали спасибо и пообещали разобраться, что за канитель.
1
hoggy
6703 / 2885 / 494
Регистрация: 15.11.2014
Сообщений: 6,485
Завершенные тесты: 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++.
5
03.03.2015, 22:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.03.2015, 22:35
Привет! Вот еще темы с ответами:

Определить, является ли число полным квадратом - C#
Добрый вечер! Помогите, пожалуйста, решить задачу - &quot;Для введенного пользователем числа определить, является ли оно полным...

Определить, что введенное число является полным квадратом - Pascal ABC
Рекомендация к заданию:Написать программу, в результате выполнения которой булевская переменная t получает значение TRUE, если выполняется...

Определить, что натуральное число N является полным квадратом - Pascal ABC
помогите пожалуйста решить составить линейную программу, печатающую значение 1, если указанное высказывание является истинным, и 0 в...

Определить, является ли приведенная функция функционально полным набором - Логика и множества
Доброй ночи, форумчане! Нужна помощь мега-мозгов :) Буду очень благодарна. Определить, является ли приведенная функция функционально...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

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