Reputation: 143
I am trying to write a function which would Print Data on the console. The function is to be templated as it should accept different types of Data.
The code is as shown below:
template<typename DataType>
void PrintData(DataType *X)
{
for (DataType Data : X)
{
cout << Data << "\t";
}
cout << endl;
}
int main()
{
int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
PrintData(nArray);
PrintData(dArray);
system("pause");
return EXIT_SUCCESS;
}
I get an error that variable Data is undeclared in the templated function PrintData.
error C2065: 'Data' : undeclared identifier
error C3312: no callable 'begin' function found for type 'double *'
error C3312: no callable 'begin' function found for type 'int *'
error C3312: no callable 'end' function found for type 'double *'
error C3312: no callable 'end' function found for type 'int *'
Any help would be appreciated. Thanks
Upvotes: 3
Views: 1951
Reputation: 4131
As Igor suggested, If at all you wish to use DataType *
then you need to do something like this
#include <iostream>
#include <iterator>
using namespace std;
template <typename DataType, size_t N>
void PrintData(DataType (&X)[N])
{
for (auto i : X)
cout << i << "\t";
cout << endl;
}
int main()
{
int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
PrintData(nArray);
PrintData(dArray);
return EXIT_SUCCESS;
}
Output
7 5 4 3 9 8 6
4.3 2.5 -0.9 100.2 3
Explanation:
If you see void PrintData(int* nArray);
& void PrintData(int (&nArray)[7] );
are similar declarations, except that seconds one tells where array ends.
Template function
template <typename DataType, size_t N>
void PrintData(DataType (&X)[N])
is deduced as'
void PrintData(int (&nArray)[7] )
You could also write
void PrintData(int (&nArray)[7] )
{
for (auto i : nArray)
cout << i << "\t";
cout << endl;
}
Upvotes: 1
Reputation: 1190
Assuming you have included the iostream
header file and the using namespace std;
directive. Then your problems are:
DataType *
. Your code makes X
a pointer, which is different from array. Use DataType const&
or DataType&&
instead.iterator
header file which provides the begin
and end
function for C-style array.The following code works for me.
#include <iostream>
#include <iterator>
using namespace std;
template<typename DataType>
void PrintData(DataType const& X)
{
for (auto Data : X)
{
cout << Data << "\t";
}
cout << endl;
}
int main()
{
int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
PrintData(nArray);
PrintData(dArray);
return EXIT_SUCCESS;
}
As commented by Igor Tandetnik, you may use template<struct DataType, size_t N>
if you want to refer the size of the array.
Update:
template<struct DataType>
and DataType *X
, DataType
is deduced as int
and double
, and X
is a pointer which is not a container.template<struct DataType, size_t N>
and DataType (&X)[N]
, DataType
is deduced as int
and double
, and X
is an array which can be used with range-based for loop.template<struct DataType>
and DataType&& X
or DataType const& X
, DataType
is deduced as int[7]
or double[5]
, and X
is an array as well.Upvotes: 4
Reputation: 708
You have some problems:
1) DataType must be a container. So, try to use:
std::vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
std::vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };
2) You are not going to change the container. It's better to pass container by const reference:
template<typename DataType>
void PrintData(const DataType & X);
3) Change the loop like this:
for (const auto & value : X) {
std::cout << value << "\t";
}
Code example:
#include <iostream>
#include <vector>
template<typename DataType>
void PrintData(const DataType & X) {
for (const auto & value : X) {
std::cout << value << "\t";
}
std::cout << std::endl;
}
int main() {
std::vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
std::vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };
PrintData(nArray);
PrintData(dArray);
return 0;
}
Upvotes: 1
Reputation: 76391
The problem is that you're passing the name of the array (e.g., nArray
), which is just a pointer to the first element, basically. However, new-style for
loops expect something on which you can call begin
and end
- a range.
The following changes make it work by using a vector
instead of an array. Note that there are very few differences otherwise, and, in general, very few reason to use C-style arrays in contemporary C++.
#include <iostream>
#include <vector>
using namespace std;
template<typename DataType>
void PrintData(const DataType &X)
{
for (const auto &Data : X)
{
cout << Data << "\t";
}
cout << endl;
}
int main()
{
vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };
PrintData(nArray);
PrintData(dArray);
system("pause");
return EXIT_SUCCESS;
Upvotes: 2