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