Possible to instantiate templates using a for loop in a C++14 constexpr function?
c++, c++14, constexpr
Solution
That aside, is it mandated by the C++14 standard, and if so, does anyone know why this syntax wouldn't be allowed (simple oversight or to protect against something)?
That's because `constexpr` is not exclusive to compile-time computations or usage. A `constexpr` function is just that, allowing a function (or variable) to be used in a constant expression. Outside of that, they're regular functions. A constant expression just so happens to be required in certain contexts such as `static_assert` or array sizes, etc that are compile-time only situations.
You'll notice in your code that you loop through a variable but the variable you're looping through itself isn't `constexpr` so it isn't a constant expression to be used in that template instantiation of `N`. As it stands, it's no different than doing this in C++11:
constexpr bool f(int x) {
static_assert(x > 10, "..."); // invalid
return true;
}
Which is obviously invalid because as I mentioned earlier, you don't have to use `constexpr` functions in exclusive compile-time situations. For example, nothing is stopping you from doing this:
constexpr int times_ten(int x) {
return x * 10;
}
int main() {
int a = times_ten(20); // notice, not constexpr
static_assert(times_ten(20) == 200, "...");
static_assert(a == 200, "..."); // doesn't compile
}
Problem
I've been messing around with an SVN build of clang to experiment with the relaxed rules for `constexpr`. One of the things I've been unable to determine as of yet is whether it's possible to loop through the elements inside a tuple at compile-time in a constexpr function. Because I don't have a C++14 compliant standard library to test on, I've prepared the following equivalent test: ``` template<int N> constexpr int foo() { return N; } constexpr int getSum() { auto sum = 0; for (auto i = 0; i < 10; ++i) { sum += foo<i>(); } return sum; } constexpr auto sum = getSum(); ``` The interesting part here is `foo<i>()`. In a non-constexpr function I would expect this to fail to compile, because you simply cannot use a runtime int to generate a compile-time instantiation of a template. Because this is a `constexpr` function, however, I question whether this would be possible. In particular, the value is known at compile-time, even if it is allowed to mutate. I know that the following code will compile: ``` constexpr auto nValue = 2; foo<nValue>(); ``` In SVN clang, my first example does not: ``` test2.cpp:19:12: error: no matching function for call to 'foo' sum += foo(); ^~~~~~ test2.cpp:11:15: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'N' constexpr int foo() { ^ ``` For starters, I struggle to interpret the second part of this error message. That aside, is it mandated by the C++14 standard, and if so, does anyone know why this syntax wouldn't be allowed (simple oversight or to protect against something)?