2012-06-15 3 views
1

static_assert, кажется, очень приятная функция вместе с шаблонами.C++ 11 static_assert (и функции, которые будут использоваться в нем)

Однако у меня возникли проблемы с поиском функций в стандартной библиотеке для проведения различных тестов во время компиляции.

Например, я ищу функцию для проверки того, является ли тип подтипом другого. boost::is_base_of делает эту работу, однако, сопоставимой функцией в std, поэтому мне не нужно полагаться на boost.

В принципе, есть ли хороший источник для списка функций, которые могут использоваться в static_assert и содержатся в стандартной библиотеке C++ 11?

Когда static_assert выполнено? Могу ли я разместить его в любом месте шаблона, и он оценивается для каждой инициализации шаблона? Может ли он использоваться для ограничения параметров шаблона как определенного подтипа класса?

+1

Вы пробовали ['std :: is_base_of'] (http://en.cppreference.com/w/cpp/types/is_base_of)? –

ответ

8

Посмотрите на окончательный C++11 draft, раздел 20.7, в частности заголовок <type_traits>.

Что вы спрашиваете, является: std::is_base_of<base, derived>::value;

Что касается Вашего вопроса: static_assert можно оценить каждый раз, когда компилятор считает нужным, но это, как правило:

  • В шаблоне: если выражение использует зависимые имена , в момент устаревания; иначе, во время определения.
  • Из шаблона: во время определения.
+0

отлично, спасибо! Это именно то, что я искал. Могу ли я использовать его для ограничения параметра типа шаблона? – gexicide

+1

@gexicide - Да, это на самом деле причина для . – rodrigo

+2

n3092 на самом деле примерно за год до окончательного варианта. n3290 - это последний доступный черновик до того, как стандарт был закончен. Вероятно, вы должны использовать n3337, который сразу после стандартизации, и единственные отличия от официального стандарта - это исправленные опечатки и тому подобное. – bames53

5

В дополнение к ответу @ Rodrigo (он был быстрее ...),

При статической проверки выполняется? Могу ли я разместить его в любом месте шаблона, и он оценивается для каждой инициализации шаблона? Может ли он использоваться для ограничения параметров шаблона как определенного подтипа класса?

К сожалению, нет. Например, static_assert(false, "bummer"); является всегда выполнен, независимо от того, шаблон. Это, в частности, не удается, если вы хотите (частично) специализировать шаблон.

Стандарт (§7.4) говорит:

[Если условие static_assert является false] программа плохо формируется, и в результате диагностическое сообщение (1.4) включает в себя текст string- буквально, [...]

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

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

Так следующее потерпит неудачу:

template <typename T> 
struct some_type { 
    static_assert(false, "T must be a pointer type"); 
}; 

template <typename T> 
struct some_type<T*> { 
    // … 
}; 

Наконец, я настоятельно рекомендую вам прочитать статью Marthino на More type traits, который подробно этот процесс больше, и дает советы о том, как решить множество проблем, связанных с отличительным признакам элегантно.

+0

+1 Можете ли вы предоставить ссылку на стандарт? –

+1

Как насчет 'template struct X {static_assert (std :: is_base_of :: значение,« T должно быть получено из Y! »);' – gexicide

+1

@gexicide Хорошо, что очевидно работает, поскольку условие теперь зависит от типов 'Y 'и' T', и он * не может быть разрешен без их знания). –