I'd like a template function that returns some initialisation.
I did the following:
#include<iostream>
#include<array>
template <typename T>
inline static constexpr T SetValues()
{
if(std::is_integral<T>::value)
{
std::cout<<"int\n";
return T{1};
}
else
{
std::cout<<"array\n";
T arr = {1,2,3,4};
return arr;
}
}
int main()
{
int a = 6;
std::array<int, 4> arr = {2,2,2,2};
a = SetValues<decltype(a)>();
arr = SetValues<decltype(arr)>();
return 0;
}
which correctly initialises the int but in case of the array I get the error
scalar object ‘arr’ requires one element in initializer
How should I initialise and return the array?
CodePudding user response:
The problem is that, when T = int
, you're trying to trying to initialize int arr
with initializer list {1, 2, 3, 4}
in the else
branch. Even if you don't execute the else
branch, the compiler still has to compile it and int arr = {1, 2, 3, 4}
is invalid syntax.
On C 17 (and higher), you can get away with if constexpr
:
template <typename T>
inline static constexpr T SetValues() {
if constexpr (std::is_integral<T>::value) {
std::cout << "int\n";
return T{1};
} else {
std::cout << "array\n";
T arr = {1, 2, 3, 4};
return arr;
}
}
With if constexpr
, the compiler won't compile the else
branch when T
is an integral type (e.g. int
) and will not compile the if
branch when T
is not an integral type.