Please help me figure out what is wrong with my code...

#include <iostream> // required to perform C++ stream I/O
#include <iomanip> // required for parameterized stream manipulators
using namespace std; // for accessing C++ Standard Library members
//declaration of calculateAverage function-template prototype
template <class T>
T calculateAverage(T dataValue[], int size)
// function main begins program execution
;int main()
{
int classSize; // size of the class
// prompt the user for and input class size
cout << "\nEnter the number of students in the class: ";
cin >> classSize;
// determine whether the user input a valid value
while ( classSize <= 0 )
{
cout << "\nError: Please enter a positive value" << endl;
// prompt the user for and input class size
cout << "\nEnter the number of students in the class: ";
cin >> classSize;
} // end while
// dynamically allocate memory for the tests array
int *tests = new int[ classSize ];
// dynamically allocate memory for the GPA's array
double *GPAs = new double[ classSize ];
for ( int count = 0; count < classSize; count++ )
{
// prompt the user for and input the standardized test scores
cout << "\nEnter student #" << count + 1 << "'s standardized "
<< "test score (0 - 1600): ";
cin >> tests[ count ];
 
// determine whether the user entered valid input
while ( tests[ count ] < 0 || tests[ count ] > 1600 )
{
cout << "\nError: Please enter a value between 0 and 1600"
<< endl;
// prompt the user for and input the standardized test score
cout << "\nEnter student #" << count + 1 << "'s "
<< "standardized test score (0 - 1600): ";
cin >> tests[ count ];
} // end while
// prompt the user for and input the student's GPA
cout << "Enter student #" << count + 1 << "'s GPA "
<< "(0.0 - 4.0): ";
cin >> GPAs[ count ];
// determine whether the user entered valid input
while ( GPAs[ count ] < 0.0 || GPAs[ count ] > 4.0 )
{
cout << "\nError: Please enter a value between 0.0 and 4.0"
<< endl;
 
// prompt the user for and input the student's GPA
cout << "\nEnter student #" << count + 1 << "'s GPA "
<< "(0.0 - 4.0): ";
cin >> GPAs[ count ];
} // end while
 
} // end for
// calculate and display the standardized test and GPA averages
cout << setprecision(3);
cout << "The class average test score is: " << calculateAverage<int>(tests,classSize)
<< "\nThe class average GPA is: " << calculateAverage<double>(GPAs,classSize);
return 0; // indicate that program ended successfully
} // end function main
T calculateAverage(T dataValue[], int size);
{
T total=0;
for(i=0; i<size; i++)
total = total + dataValue[i];
return(total / size);
}

I am actually getting the following errors:
C:\Data\ET486Final\CollegeApplications.cpp(84) : error C2146: syntax error : missing ';' before identifier 'calculateAverage'
C:\Data\ET486Final\CollegeApplications.cpp(84) : error C2501: 'T' : missing storage-class or type specifiers
C:\Data\ET486Final\CollegeApplications.cpp(84) : fatal error C1004: unexpected end of file found

All 3 errors point to "T calculateAverage(T dataValue[], int size);". Thank you in advance for your help.

Your code is difficult to read - try adding some formatting!

a few points to note

1) Why is there a semicolon before int main() ? Presumably its supposed to belong to the function prototype 2 lines up - you should put it there instead, else it just looks like an error to anyone who's casually reading your code. (This won't stop the program from working, its just bad style IMO)

2) Get rid of the semicolon at the end of the line where you define calculateAverage after the end of main

3) calculateAverage is presumably supposed to be a templated function, so you need to specify template <typename T> before you define the function, else the compiler has no idea what T is.

4) inside calculateAverage there is a for loop - you haven't declared 'i' before attempting to initialise it

If you fix those errors, the program should compile (Although I haven't checked the logic of the program)

Thanks for the help. But it isnt helping. Isnt

template <class T>
T calculateAverage(T dataValue[], int size)

what you meant by your 3rd point? And I tell it what T is in the cout before the return 0; when I call the function. Also just to clarify, I have made the changes in Bench's post (1st, 2nd, and 4th items).

The compiler must be told every single time a section of code is templated,
essentially, you need the template parameter list for both the forward declaration at the top of your program (which you already have) and then again when you actually define it. ie

template <typename T>
T calculateAverage(T dataValue[], int size)
{
    T total=0;
    for(int i=0; i<size; i++)
        total = total + dataValue[i];
    return(total / size);
}

Simply having the template parameter list at the forward declaration isn't enough - since when you reach the definition of calculateAverage, the compiler doesn't know what T is (template parameter lists are not strictly part of a function signature)

It is worth noting that though those two things ( <typename T> and <class T> ) are interchangeable in most of the cases there are some senarios where you must use <typename T>.

Eg. Suppose you want to create a templated class with something like this:

template < class T, T::member> struct ABC { // }

This actually won't work since in templated class you are passing the type and then the member of the same type. So in such cases <class T> won't work.

You can do somethings like:

// correct
template < class T, typename T::member> struct ABC { // }

//correct 
template < typename T, typename T::member> struct ABC { // }

//incorrect since the compiler won't come to know that T::member
// is a type.
template < typename T, T::member> struct ABC { // }
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cuda.h>
#include <assert.h>


 //#include "cudaUtilities.h.cu"

// Timer variables
//unsigned int cpuTimerVariable;
//cudaEvent_t eventTimerStart;
//cudaEvent_t eventTimerStop;

typedef struct 
{
 unsigned long value;
 unsigned long centroid; 
}valpoint;

typedef struct
{ 
 unsigned long value; 
 unsigned long numMembers;
 }centroid; 


  const unsigned long numElements = 1024*1024;
  const int numClusters = numElements / 256; 
  //unsigned int mem_size;
  valpoint *d_idata, *h_odata;
 centroid* d_centroids;

//CUT_DEVICE_INIT(); 
//CUT_SAFE_CALL( cutCreateTimer( &timer));
  unsigned int mem_size = numElements * sizeof(valpoint);

// allocate host memory 

valpoint* h_idata = (valpoint*) malloc( mem_size); 
centroid* h_centroids = (centroid*) malloc (numClusters * sizeof(centroid));

// initialize the memory 
for(unsigned long i = 0; i < numElements; ++i)
{ 
h_idata[i].value = i + 0xc0000000 ;
 if (i % 128 == 0)
    {
 //estimate the centroids
 h_centroids[i/256].value = i + 0xc0000000; 
h_centroids[i/256].numMembers = 0;
    }
 }
//CUT_SAFE_CALL( cutStartTimer( timer));
// allocate device memory for data points

 cudaMalloc( (void**) &d_idata, mem_size);
// copy data points to device 

cudaMemcpy( d_idata, h_idata, mem_size, cudaMemcpyHostToDevice) ;
// copy centroids to device
__constant__ centroid constData[4096];
  cudaMemcpyToSymbol( constData, h_centroids, sizeof(centroid)* numClusters);

//__constant__ centroid constData[4096];
 __global__ void  testKernel( valpoint* g_idata, centroid* g_centroids, int numClusters)

{
     unsigned long valindex = blockIdx.x * 512 + threadIdx.x ;
     int k, myCentroid; 
     unsigned long minDistance; 
     minDistance = 0xFFFFFFFF;
 for (k = 0; k<numClusters; k++)
 if (abs((long)(g_idata[valindex].value constData/*g_centroids*/[k].value)) <minDistance)
    {
     minDistance = abs((long)( g_idata[valindex].value constData[k].value)); 
     myCentroid = k; 
    }
    g_idata[valindex].centroid = __constData[myCentroid].value; 
    //__syncthreads();
}




        // setup execution parameters 

dim3 grid( numElements / 512, 1); 
//2048 blocks.
// numElements can be up to 32 Mega samples

 dim3 threads( 512, 1, 1); 

// each block having 512 threads. The maximum is 768

printf("Main thread: about to dispatch kernel...\n");

// execute the kernel

 testKernel<<< grid, threads >>>( d_idata, d_centroids, numClusters);
//getLastCudaError("Kernel execution failed");

//allocate mem for the result on host side

 h_odata = (valpoint*) malloc( mem_size);

// copy result from device to host

 cudaMemcpy( h_odata, d_idata, mem_size, cudaMemcpyDeviceToHost) ;
 //CUT_SAFE_CALL( cutStopTimer( timer)); printf( "Time: \%f(ms)\n", 
 //cutGetTimerValue( timer)); CUT_SAFE_CALL( cutDeleteTimer( timer));

// cleanup memory 

free( h_idata); 
free( h_odata);
 //checkCudaErrors(cudaFree(d_idata)); 
 //checkCudaErrors(cudaFree(d_centroids));
 //CUT_EXIT(argc, argv);
This article has been dead for over six months. Start a new discussion instead.