Как записать шаблон 'is_complete'?

Да, проверьте значения констант типов float и double, например:
float.PositiveInfinity
float.NegativeInfinity
Эти значения соответствуют IEEE -754, так что вы можете проверить, как это работает точно, чтобы вы знали, когда и как вы можете получить эти значения при выполнении расчетов. Более подробная информация здесь .

21
задан Community 23 May 2017 в 11:45
поделиться

4 ответа

Ответ Алексея Малистова можно использовать в MSVC с небольшими изменениями:

namespace 
{
    template<class T, int discriminator>
    struct is_complete {  
      static T & getT();   
      static char (& pass(T))[2]; 
      static char pass(...);   
      static const bool value = sizeof(pass(getT()))==2;
    };
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value

К сожалению, предопределенный макрос __ COUNTER __ не является частью стандарта, поэтому он не будет работать на всех компиляторах.

14
ответ дан 29 November 2019 в 20:43
поделиться
template<class T>
struct is_complete {
    static T & getT();
    static char (& pass(T))[2];
    static char pass(...);

    static const bool value = sizeof(pass(getT()))==2;
};
9
ответ дан 29 November 2019 в 20:43
поделиться

Я не могу найти в стандарте ничего, что гарантировало бы, что sizeof для неполного типа вернет 0. Однако он требует, чтобы если T в какой-то момент был неполным, но завершился позже в эта единица перевода, что все ссылки на T относятся к одному и тому же типу - так что, как я читал, даже если T неполный там, где был вызван ваш шаблон, нужно было бы сказать, что он был завершен, если T завершен где-то в этом переводе ед.

0
ответ дан 29 November 2019 в 20:43
поделиться

Боюсь, что вы не сможете реализовать такие is_complete типовые признаки. Реализация, данная @Alexey, не компилируется на G++ 4.4.2 и G++ 4.5.0:

ошибка: инициализирующий аргумент 1 'static char (& is_complete::pass(T))[2] [с T = Foo]'

На моем Mac, с G++ 4.0. 1 вычисляющий is_complete::value, где struct Foo; является неполными значениями для true, что еще хуже ошибки компилятора.

T может быть как полным, так и неполным в одной и той же программе, в зависимости от единицы трансляции, но это всегда один и тот же тип. Как следствие, как было прокомментировано выше, is_complete тоже всегда один и тот же тип.

Так что если вы уважаете is_complete, то невозможно, чтобы is_complete вычислял разные значения в зависимости от того, где он используется; в противном случае это означало бы, что у вас разные определения для is_complete, которые запрещены в рамках УСО.

EDIT: Как принятый ответ, я сам взломал решение, которое использует макрос __COUNTER__, чтобы инстанцировать другой тип is_complete каждый раз, когда используется макрос IS_COMPLETE. Однако с gcc я не смог заставить SFINAE работать в первую очередь.

.
2
ответ дан 29 November 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: