Начал читать Александреску, и там есть приблизительно такая конструкция (только названия изменены):
Class A;
(void) sizeof(( Checker<true>( A() ) ));
1. пришлось добавить скобки в sizeof(). иначе ошибка "cast to function type is illegal". Не подскажите что это значит.
2. какой смысл приведения к void.
Спасибо.
ошибся, должно быть:
class A{};
(void) sizeof(( Checker<true>( A() ) ));
Здравствуйте, Аноним, Вы писали:
А>ошибся, должно быть:
А>А>class A{};
А>(void) sizeof(( Checker<true>( A() ) ));
А>
Поменьшк всяких извращенцев типа Александреску читай и всё будет хорошо
Как мне однажды объяснил jazzer, это приведение к (void) наверное, чтоб избежать ворнинга о бессысленном с точки зрения компилятора выражении.
void fun()
{
1 + 2;
}
"ComeauTest.c", line 3: warning: expression has no effect
1 + 2;
^
void fun()
{
(void)(1 + 2);
}
нету ворнингов
Здравствуйте, Аноним, Вы писали:
А>1. Не подскажите что это значит.
А>2. какой смысл приведения к void.
Это разновидность static assert'а (конструкция, которая
пытается скомпилироваться, но нигде не применяется).
Оператор sizeof(), в отличие от других, не требует вычисления операнда — только интересуется его типом.
Это позволяет, в частности, использовать его для дискриминации типов.
typedef char false_type;
typedef struct { char t[100]; } true_type;
template<class T, class U> struct is_convertible
{
// нигде не определены, только объявлены
true_type discriminator(U u);
false_type discriminator(...);
static T& t;
enum { value = sizeof(true_type) == sizeof(discriminator(t)) }
};
В разных контекстах приходится использовать разные static-assert'ы.
* шаблоны классов
* размеры массивов
* сигнатуры функций
(void)(expression) ингибирует любое применение этого выражения, кроме как в инструкции:
template<bool V> struct Asserter
{
typedef int type;
};
template<> struct Asserter<false>
{
// идентификатор type не объявлен
};
#define STATIC_ASSERT_EXPR(expr) \
(void)( sizeof( typename Asserter<(expr)>::type ) )
// | | | +-- предмет облома для компилятора
// | | +-- выражение, от которого зависит успех/облом
// | +-- просто взять тип; никаких действий в рантайме!
// +-- избавляемся от неуместного применения этого макроса
...
main()
{
STATIC_ASSERT_EXPR(true); // ок
STATIC_ASSERT_EXPR(false); // ошибка: неизвестный тип Asserter<false>::type
printf("%d", STATIC_ASSERT_EXPR(true)); // ошибка использования: rvalue типа void
У Александреску, похоже, предметом облома выступило существование публичного конструктора без параметров, то есть
template<bool V> struct Checker { Checker(){} };
template<> struct Checker<false> { private: Checker() {} };
J>а ведь я уже и сам не помню
Давно это было, я еще вроде как под Анонимом зашел