утверждение времени компиляции на основе шаблона с настраиваемыми сообщениями может быть скомпилировано только в некоторых компиляторах

Этот код демонстрирует утверждение времени компиляции с использованием шаблона. Я обнаружил, что его можно скомпилировать только с помощью g ++ (4.4.7) со следующей строкой cmd.

$ g++ -std=c++98 a.cpp -o a

Nether icc (13.0.1) или Visual C ++ (14.00.50727.762 для 80x86) не могут его скомпилировать. Для icc он генерирует сообщение об ошибке, подобное этому

$ icpc a.cpp -o a
a.cpp(13): error: non-integral operation not allowed in nontype template argument
      COMPILE_TIME_ASSERT(true && "err msg");
      ^

a.cpp(13): error: class "CompileTimeAssert<<error-constant>>" has no member "Check"
      COMPILE_TIME_ASSERT(true && "err msg");
      ^

compilation aborted for a.cpp (code 2)

Однако я обнаружил, что утверждения типа true && "err msg" широко используются в утверждениях во время выполнения как Добавить пользовательские сообщения в assert? < / а>

Вопросы

  1. Можно ли решить эту проблему без изменения кода, только с правильными параметрами компиляции?
  2. Если не может, какие альтернативные методы времени компиляции утверждают с помощью настраиваемых сообщений?

Демо-код выглядит следующим образом.

#include <iostream>

template<bool B> class CompileTimeAssert { };
template<> class CompileTimeAssert<true> {
 public:
  static inline void Check() { }
};

#define COMPILE_TIME_ASSERT(b) CompileTimeAssert<(b)>::Check()

int main()
{
    COMPILE_TIME_ASSERT(true && "err msg");
    std::cout<<(true && "err msg")<<std::endl;
    return 0;
}

person kangshiyin    schedule 25.07.2013    source источник
comment
вам обязательно нужно использовать стандарт std = c ++ 98?   -  person Yochai Timmer    schedule 25.07.2013
comment
@YochaiTimmer НЕТ, я просто хочу показать, что g ++ может скомпилировать код даже с этой опцией   -  person kangshiyin    schedule 25.07.2013
comment
Для аргументов шаблона, не являющихся типом, допустимы только целые аргументы.   -  person dans3itz    schedule 25.07.2013
comment
@ dans3itz вы имеете в виду, что gcc не соответствует стандарту?   -  person kangshiyin    schedule 25.07.2013
comment
@Eric, так почему бы вам просто не использовать static_assert (C ++ 0x и C ++ 11)   -  person Yochai Timmer    schedule 25.07.2013
comment
@YochaiTimmer пытается не огорчать старые компиляторы.   -  person kangshiyin    schedule 25.07.2013
comment
Найдите определение BOOST_STATIC_ASSERT_MSG (x, msg)   -  person dans3itz    schedule 25.07.2013
comment
На самом деле, похоже, что опция ускорения даже не поддерживает сообщение без минимального целевого значения 0x (раннее принятие / 03 черновик).   -  person dans3itz    schedule 25.07.2013
comment
Я никогда не использовал этот подход для статического утверждения (я использовал typedef char assert_XXX[(condition?1:-1)];), но вы могли бы подумать об изменении макроса, чтобы строка передавалась в функцию: COMPILE_TIME_ASSERT(condition,"Message") расширился бы до CompileTimeAssert<(condition)>::Check("Message"), который после адаптации подписи, вероятно, будет легче переваривать для всех компиляторов   -  person David Rodríguez - dribeas    schedule 25.07.2013


Ответы (1)


Ответ на первый вопрос - «Нет». Аргумент, который вы передаете шаблону, называется так называемым «аргументом шаблона, не относящимся к типу». По стандарту такими аргументами должны быть:

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

Выражение типа true && "err msg", строго говоря, не может быть определено во время компиляции. Вот почему его можно использовать с утверждениями времени выполнения, но не во время компиляции. G ++ демонстрирует здесь нестандартное поведение.

В качестве ответа на второй вопрос предлагаю следующую закономерность:

#define STATIC_ASSERT(e,m) extern char (*__static_assert_failed(void)) [ 1 - 2*!(e) ] 

__static_assert_failed здесь указатель на внешнюю функцию, возвращающую массив символов. Массив имеет размер 1 - 2*!(e), который становится отрицательным, если e ложно, вызывая ошибку времени компиляции.

person Yury Bayda    schedule 27.10.2013