0
#include <iostream>
#include <stdexcept>

// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

// literal class
class conststr {
    const char * p;
    std::size_t sz;
 public:
    template<std::size_t N>
    constexpr conststr(const char(&a)[N]) : p(a), sz(N-1) {}
    // constexpr functions signal errors by throwing exceptions from operator ?:
    constexpr char operator[](std::size_t n) const {
        return n < sz ? p[n] : throw std::out_of_range("");
    }
    constexpr std::size_t size() const { return sz; }
};

constexpr std::size_t countlower(conststr s, std::size_t n = 0,
                                             std::size_t c = 0) {
    return n == s.size() ? c :
           s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n+1, c+1) :
           countlower(s, n+1, c);
}

// output function that requires a compile-time constant, for testing
template<int n> struct constN {
    constN() { std::cout << n << '\n'; }
};

int main()
{
    std::cout << "4! = " ;
    constN<factorial(4)> out1; // computed at compile time

    volatile int k = 8; // disallow optimization using volatile
    std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time

    std::cout << "Number of lowercase letters in \"Hello, world!\" is ";
    constN<countlower("Hello, world!")> out2; // implicitly converted to conststr
}

I was looking at the link Weird constexpr argument in code where the accepted answer states that The parameter const char(&a)[N] is a reference to an array.

So if const char(&a)[N] is a reference to an array, does p(a) in the constexpr constructor mean that a is a pointer to a character constant?

user2635088
  • 1,598
  • 1
  • 24
  • 43
  • 1
    The array to pointer conversions is still applied. Therefore `p` still points to the first character of `a`. – David G Nov 29 '17 at 05:53
  • AFAIK, `const char (&a)[N]` is a reference to an array. Note the parentheses - without it would be an array of references. Hence, `a` is the array. Usually, arrays mostly decay to pointers with few exceptions (e.g. `sizeof`). – Scheff's Cat Nov 29 '17 at 05:54
  • I used this reference to array in rare cases as arrays may not be used as parameters but references to arrays. Hence, the array reference parameter has still array type, array size, etc. (Impossible to do it in C as there are no references...) – Scheff's Cat Nov 29 '17 at 05:56
  • aah so its not an std::array, but closer to a c-style array? – user2635088 Nov 29 '17 at 06:02

0 Answers0