I got this compile time string comparison from another thread using constexpr and C++11 (http://stackoverflow.com/questions/5721813/compile-time-assert-for-string-equality). It works with constant strings like “OK”
constexpr bool isequal(char const *one, char const *two) {
return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1))
: (!*one && !*two);
}
I am trying to use it in the following context:
static_assert(isequal(boost::mpl::c_str<boost::mpl::string<'ak'>>::value, "ak"), "should not fail");
But it gives me an compilation error of static_assert expression is not an constant integral expression.
Can I do this?
The problem is that the
valuemember ofmpl::c_stris not marked asconstexpr. Until the library authors decide to include support forconstexpr, you are pretty much screwed, unless you are willing to modify your Boost code (or create your own version ofc_str). If you decide to do so, the modification is quite simple: you just need to locateBOOST_ROOT/boost/mpl/string.hppand replace thisby this
Hmm, after digging a bit more, it turns out the problem is more complex than I thought. In fact, static constants can be used in constexpr; the true problem is that
c_str<T>::valueis an array, and your function takes pointers as parameters. As a consequence, the compiler needs to decay the array, which boils down to taking the address of its first element. Since addresses are a runtime concept, it is not possible to take the address of an object in a constexpr.To solve the issue, I tried to write a second version of
isequalthat operates on arrays rather than on pointers:Unfortunately, this code does not work with
mpl::c_str; in fact, the problem is that static const arrays are not compile-time values, unlike integral constants. So we’re back the beginning: unlessvalueis marked asconstexpr, there is no way to use it in a constant expression.As to why the code I gave initially fails, I can’t answer right now as my version of gcc (4.6) fails to compile it altogether…
After updating gcc, it turns out
valueneeds to be defined outside the class, even though it is declared and initialized in the class (see this question). I edited the code above with the correction.