I would like to create a macro which can compare 2 strings, and emit a compile time error if the condition isn't met. This could be though of as a compile time assertion.
I'm not sure how I could do this.
For instance:
STATIC_COMPARE("THIS STRING","THIS STRING") -> would emit a compile time error
STATIC_COMPARE("THIS STRING","THIS OTHER STRING) -> wouldn't emit a compile time error.
The macro would look something like
#define STATIC_COMPARE(str1,str2) if (str1==str2) emit an error with a message
So I guess the question boils down to being able to compare the 2 strings at compile time.
You can do this with C++11 by using a constexpr
function:
constexpr bool strings_equal(char const * a, char const * b) {
return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
}
(See a demo)
It's not possible to do this prior to C++11, with the caveat that many compilers will compile equal string literals to be a pointer to the same location. On these compilers it's sufficient to compare the strings directly since they will both be evaluated as equal pointers.
You can use constexpr
functions. Here's the C++14 way:
constexpr bool equal( char const* lhs, char const* rhs )
{
while (*lhs || *rhs)
if (*lhs++ != *rhs++)
return false;
return true;
}
Demo.
This can be done in C++ 11 using constexpr. By defining a recursive function you can check that the string are equal or not.
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");
This code I used thanks to Johannes Schaub and you can see the full SO post here
Starting with C++17 std::string_view is available. It supports constexpr comparisson:
#include <string_view>
constexpr bool strings_equal(char const * a, char const * b) {
return std::string_view(a)==b;
}
int main() {
static_assert(strings_equal("abc", "abc" ), "strings are equal");
static_assert(!strings_equal("abc", "abcd"), "strings are not equal");
return 0;
}
Demo