Вы правы, что все используемые вами типы являются литеральными типами , но есть еще одно требование для функции constexpr
.
Функция constexpr
должна вызываться при хотя бы один набор аргументов, чтобы вызов был константным выражением.
Проблема в том, что z.size()
никогда нельзя вызывать в константном выражении, потому что string
'size
функция не объявлена constexpr
.
Если объявленная функция constexpr
никогда не может использоваться в качестве константного выражения, то программа имеет неопределенное поведение , и компилятор может или не может предупредить или напечатать ошибку о it.
Если вы измените функцию так, чтобы ее можно было использовать в качестве константного выражения хотя бы для одного набора аргументов вызова, то в определении больше не будет ошибки:
constexpr bool a (bool b, const string &z , const string &zz)
{
return b ? false : (z.size() > zz.size());
}
Вы все еще не можете вызывать это как часть постоянного выражения с b
как false
.
Как уже упоминалось в комментариях, вы можете заставить эту функцию работать (предполагая, что это вызов редактирование с аргументами, которые можно использовать в постоянном выражении) с использованием string_view
вместо const string&
начиная с C ++ 17. (Требуется #include<string_view>
). Это работает, потому что std::string_view
является литеральным типом (в частности, он имеет constexpr
конструкторы), и его size
функция также равна constexpr
.