I can't use constexpr value in function, as opposed to outside of the function.
I can use auto ar1 = std::array<int, il.size()>(); in scope where il is defined.
But I can't use { return std::array<T, il.size()>();} in constexpr-function il_to_array()
Why can not I use constexpr value in function, but I can do the same in block scope of this value?
http://ideone.com/5g0iRE
#include <iostream>
#include <initializer_list>
#include <array>
constexpr size_t size_to_size(size_t v) { return v; } // 1 - OK
template<typename T>
constexpr size_t il_to_size(std::initializer_list<T> il) { return il.size(); } // 2 - OK
// 3 - error
template<typename T>
constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();}
template<size_t N>
void print_constexpr() { std::cout << N << std::endl; }
int main() {
constexpr std::initializer_list<int> il = { 1, 2, 3 };
print_constexpr<il.size()>(); // 0 - OK
print_constexpr< size_to_size(il.size()) >(); // 1 - OK
print_constexpr< il_to_size(il) >(); // 2 - OK
auto ar1 = std::array<int, il.size()>(); // OK - body of function: il_to_array()
//auto ar2 = il_to_array(il); // 3 - error
return 0;
}
For example, there we see, that template-constexpr-function will not fail, even if it may be or may not be constexpr - depends of T, because one of instance may be constexpr: Why does the C++ compiler makes it possible to declare a function as constexpr, which can not be constexpr?
And it can be concluded that if this is a template-function, it may be specialization any of: constexpr and non-constexpr.
And on the basis of SFINAE - if we use only constexpr-arguments then instantiates only constexpr-instance, and it does not matter that non-constexpr-function could not be instantiated.
The arguments of (constexpr) functions are not constexpr.
constexpr functions might be given arguments which were not known at compile time.
So following is valid whether v is known at compile time or not
constexpr size_t size_to_size(size_t v) { return v; }
But following function doesn't work as il is not constexpr and non type template parameter requires to be known at compile time:
template<typename T>
constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();}
This is true even if the function is only called with arguments known at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With