Reputation: 1897
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:
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
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