Reputation: 13
I have a function which has template class object as parameter. Its working fine with user defined template class object as paramerter but its giving arror with std::array object. If I am trying to execute this program
#include<iostream>
#include<array>
template<typename T1, int size>
void print(std::array<T1, size> &arr)
{
for (auto ele : arr)
std::cout << ele << " ";
}
template<int size>
void print(std::array<float, size> &arr)
{
std::cout << "its float" << std::endl;
for (auto ele : arr)
std::cout << ele << " ";
}
int main()
{
std::array<int, 3> arr{1,3,4};
std::array<float, 2> ar2{1.3, 3.4};
print(arr);
print(ar2);
return 0;
}
And getting this error
error: no matching function for call to ‘print(std::array<int, 3>&)’
print(arr);
But when I am running this program then its working fine.
#include<iostream>
#include<array>
template<class T, int size>
class Template
{
public:
std::array<T, size> arr;
};
template<typename T1, int size>
void print(Template<T1, size> &obj)
{
for (auto ele : obj.arr)
std::cout << ele << " ";
}
template<int size>
void print(Template<float, size> &obj)
{
for (auto ele : obj.arr)
std::cout << ele << " ";
}
int main()
{
Template<int, 3> array;
array.arr[0] = 1;
array.arr[1] = 2;
array.arr[2] = 3;
Template<float, 2> arr2;
arr2.arr[0] = 2.3;
arr2.arr[1] = 2.9;
print(array);
print(arr2);
return 0;
}
I don't understand why std::array<T1, size>
is not suitable match for std::array<int, 3>
but class Template<T1,size>
is suitable match for Template<int, 3>
Upvotes: 1
Views: 43
Reputation: 172934
Because the 2nd template parameter's type of std::array
is std::size_t
, but not int
; they don't match and cause template argument deduction on the non-type template parameter fails.
(emphasis mine)
If a non-type template parameter is used in the parameter list, and the corresponding template argument is deduced, the type of the deduced template argument ( as specified in its enclosing template parameter list, meaning references are preserved) must match the type of the non-type template parameter exactly, except that cv-qualifiers are dropped, and except where the template argument is deduced from an array bound—in that case any integral type is allowed, even bool though it would always become true:
Change the type to std::size_t
.
template<typename T1, std::size_t size>
void print(std::array<T1, size> &arr)
{
for (auto ele : arr)
std::cout << ele << " ";
}
template<std::size_t size>
void print(std::array<float, size> &arr)
{
std::cout << "its float" << std::endl;
for (auto ele : arr)
std::cout << ele << " ";
}
Upvotes: 4
Reputation: 3088
You were close. Use size_t instead of int. This compiles:
#include <iostream>
#include <array>
template<typename T1, size_t size>
void print(std::array<T1, size> const &arr)
{
for (auto ele : arr)
std::cout << ele << " ";
}
template<size_t size>
void print(std::array<float, size> &arr)
{
std::cout << "its float" << std::endl;
for (auto ele : arr)
std::cout << ele << " ";
}
int main()
{
std::array<int, 3> arr{1,3,4};
std::array<float, 2> ar2{1.3, 3.4};
print(arr);
print(ar2);
return 0;
}
Upvotes: 0