I have the following function:
constexpr int count_format_placeholders(const std::string_view format)
{
int count = 0;
for(int i = 0; i < format.size(); ++i)
{
if(format[i] == '{' && format[i + 1] == '}')
{
++count;
++i;
}
}
return count;
}
I have defined two functions, func and func2:
template<typename... Args>
constexpr int func(std::string_view format)
{
return count_format_placeholders(format);
}
template<typename... Args>
constexpr int func2(std::string_view format)
{
constexpr int i = count_format_placeholders(format);
return i;
}
int main()
{
constexpr std::string_view format{"{} {} {} {}:{}:{}"};
constexpr int num_placeholders = count_format_placeholders(format); //compiles
std::cout << num_placeholders << std::endl;
constexpr int num_placeholders2 = func<int, int>(format); //compiles
std::cout << num_placeholders2 << std::endl;
constexpr int num_placeholders3 = func2<int, int>(format); //doesn't compile, why?
std::cout << num_placeholders3 << std::endl;
return 0;
}
The direct call to count_format_placeholders, and func work fine. Calling func2, however, generates a format is not constant expression error.
Why is this, and how can I fix this?
Easy testing: https://godbolt.org/z/9zoWM95hh
funcbut not offunc2? Is there UB somewhere ?funcworks fine? RVO and move semantics cannot be the issue since this is compile time (but I tested disabling them anyway and they are not).