Это возможно только с C ++ 0x. Нет шансов с C ++ 03.
EDIT: функция Constexpr для C ++ 0x. Нижеследующее работает с GCC4.6, однако Стандарт явно не разрешает его, и небольшая поправка формулировки была и рассматривается для того, чтобы спецификация позволяла это.
constexpr bool isequal(char const *one, char const *two) {
return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1))
: (!*one && !*two);
}
static_assert(isequal("foo", "foo"), "this should never fail");
static_assert(!isequal("foo", "bar"), "this should never fail");
Компилятор должен отслеживать ссылки на символы строковых литералов уже во всех рекурсиях. Только окончательное чтение символов явно не разрешено (если вы щуритесь, вы можете прочитать его как разрешенное, IMO). Если ваш компилятор не хочет принимать вышеуказанную простую версию, вы можете сделать так, чтобы ваш макрос объявлял массивы, а затем сравнивал эти
#define CONCAT1(A, B) A ## B
#define CONCAT(A, B) CONCAT1(A, B)
#define CHECK_EQUAL(A, B) \
constexpr char CONCAT(x1, __LINE__)[] = A, \
CONCAT(x2, __LINE__)[] = B; \
static_assert(isequal(CONCAT(x1, __LINE__), CONCAT(x2, __LINE__)), \
"'" A "' and '" B "' are not equal!")
Это точно нормально.
CHECK_EQUAL("foo", "foo"); /* will pass */
CHECK_EQUAL("foo", "bar"); /* will fail */
Обратите внимание, что CHECK_EQUAL
может использоваться внутри функций. FCD внес изменения, чтобы позволить constexpr
функциям читать из автоматических массивов при замене их вызовов. См. DR1197 .