Sarang
Sarang

Reputation: 1897

constexpr class and template function match

I am trying out constexpr to get a feel for functionality and I see it can make template metaprogramming a bit more easier (If I am understanding it correctly).

I have this dummy example where a class has a const number field, and ctor being marked constexpr should behave like a compile time constant. Which it does but some how fails with template function matching:

#include <iostream>

class ConstNum
{
public:
    constexpr ConstNum(int num) : _num(num)
    {
    }

    constexpr int number() const
    {
        return _num;
    }

private:
    const int _num;
};


template<class T, size_t N>
constexpr int num_elements(const T (&arr) [N])
{
    return N;
}

int main()
{
    ConstNum c1(3);
    char arr[c1.number()];

    //  fails to compile here with error message:
    //  No matching function for call to num_elements
    //  
    std::cout << num_elements(arr) << std::endl;

    return 0;
}

I am running on XCode, the error message gives details about this being semantic issue: additional text being:

  1. Candidate template ignored: could not match 'const T[N]' against 'char [c1.number()]

If I replace c1.number() by 3 this compiles fine. Or If i remove the std::cout call entirely this compiles fine.

Any ideas what am I missing here. Thank you

Sarang

Upvotes: 3

Views: 345

Answers (1)

awesoon
awesoon

Reputation: 33661

Even if function marked as constexpr it may evaluate at run-time. If you want compile-time evaluation, you should add constexpr specifier to c1 object, otherwise it will be constructed at run-time:

constexpr ConstNum c1(3);

Output:

> ./main
3

Tip: Clang with enabled warnings gives the following output for your code:

main.cpp:29:13: warning: variable length arrays are a C99 feature [-Wvla-extension]
    char arr[c1.number()];

This means, that c1.number() was not evaluated at compile time, as you expected

Upvotes: 4

Related Questions