Как сделать static_assert с макросами?

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

Пример следует:

#include <iostream>

#define STATIC_ASSERT(expr, msg)               \
{                                              \
char STATIC_ASSERTION__##msg[(expr)?1:-1]; \
(void)STATIC_ASSERTION__##msg[0];          \
}

template <typename T >
class A
{
public:
int foo(const int k )
{
// does not work
STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
};

int bar(const int k )
{
// works fine
//STATIC_ASSERT( k > 9, error_msg );
return k+5;
}

int main()
{
A<int> a;
const int v = 2;

std::cout<<a.foo(v)<<std::endl;
std::cout<<bar(v)<<std::endl;

// works fine
//STATIC_ASSERT( v > 9, error_msg );
}

Я скомпилировал его с g ++ 4.7.2, с предупреждением, что VLA не поддерживаются c ++ ISO:

g++ -Wall -g  -std=c++98 -Wextra -pedantic gvh.cpp

Итак, почему компиляция не завершается неудачно, когда в методе шаблона используется STATIC_ASSERT? Есть ли способ заставить его потерпеть неудачу?

НОТА : Мне нужно решение C ++ 98 (возможно, даже C ++ 03), если возможно только с макросами.

0

Решение

До C ++ 11 я обычно делал:

typedef int static_assert_something[something ? 1 : -1];

Вы также можете посмотреть на повысить статическое утверждение. Но это слишком раздутый на мой вкус. Легко сделать вещи больше, трудно сделать их лучше.

13

Другие решения

Рассмотреть что-то вроде Boost.StaticAssert, хотя, если это недоступно для вас, вы можете попытаться определить шаблон.

template<bool>
struct static_assertion;

template<>
struct static_assertion<true> {};

Хотя у этого есть недостаток отсутствия сообщения, связанного с ним.

После небольшого поиска в StackOverflow я наткнулся на этот вопрос у которого был похожий ответ на мой и куча альтернатив для того, чтобы сделать это без повышения.

3

Это в основном ответ Максима с немного более удобным интерфейсом. Я взял это из Вот. Хорошая вещь об этом — то, что использование шаблонов препятствует тому, чтобы пользователь передал значение не-времени компиляции как условие.

template<bool Is_Condition_Met>
struct Static_assert_cpp98
{
static void apply() {static const char junk[ Is_Condition_Met ? 1 : -1 ];}
};

template<>
struct Static_assert_cpp98<true>
{
static void apply() {}
};

#define STATIC_ASSERT_CPP98(condition) Static_assert_cpp98<condition>::apply()
3

Если вы добавите вызов к рассматриваемому методу (a.foo ();), статическое утверждение не будет выполнено (только тогда метод будет скомпилирован). Вы знаете, что вы не должны статически утверждать значения времени выполнения, такие как «k», я полагаю.

1
int foo(const int k)
{
STATIC_ASSERT( k > 9, error_msg );
return k+5;
}

Статические утверждения работают только с константными выражениями во время компиляции.

k не является константным выражением времени компиляции.

Нетипичные параметры шаблона являются константными выражениями во время компиляции во время создания шаблона, поэтому вы можете адаптировать свой код следующим образом:

template <int K>
int foo()
{
STATIC_ASSERT( K > 9, error_msg );
return K+5;
}
0
По вопросам рекламы [email protected]