43

I've tried on a few different forums and can't seem to get a straight answer, how can I make this function return the struct? If I try 'return newStudent;' I get the error 'No suitable user-defined conversion from studentType to studentType exists.'

// Input function
studentType newStudent()
{   
    struct studentType
    {
        string studentID;
        string firstName;
        string lastName;
        string subjectName;
        string courseGrade;

        int arrayMarks[4];

        double avgMarks;

    } newStudent;

    cout << "\nPlease enter student information:\n";

    cout << "\nFirst Name: ";
    cin >> newStudent.firstName;

    cout << "\nLast Name: ";
    cin >> newStudent.lastName;

    cout << "\nStudent ID: ";
    cin >> newStudent.studentID;

    cout << "\nSubject Name: ";
    cin >> newStudent.subjectName;

    for (int i = 0; i < NO_OF_TEST; i++)
    {   cout << "\nTest " << i+1 << " mark: ";
        cin >> newStudent.arrayMarks[i];
    }

    newStudent.avgMarks = calculate_avg(newStudent.arrayMarks,NO_OF_TEST );
    newStudent.courseGrade = calculate_grade (newStudent.avgMarks);

}
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
tail_recursion
  • 660
  • 1
  • 7
  • 11
  • 2
    You seem to have declared two versions of `studentType` define: one outside the function and one inside the function. You should have only one definition, the one outside the function. – Dietmar Kühl Oct 06 '13 at 03:14
  • Alternatively, you can allocate it on the heap and return a pointer of type studentType. – Mike G Oct 06 '13 at 03:16

5 Answers5

45

Here is an edited version of your code which is based on ISO C++ and which works well with G++:

#include <string.h>
#include <iostream>
using namespace std;

#define NO_OF_TEST 1

struct studentType {
    string studentID;
    string firstName;
    string lastName;
    string subjectName;
    string courseGrade;
    int arrayMarks[4];
    double avgMarks;
};

studentType input() {
    studentType newStudent;
    cout << "\nPlease enter student information:\n";

    cout << "\nFirst Name: ";
    cin >> newStudent.firstName;

    cout << "\nLast Name: ";
    cin >> newStudent.lastName;

    cout << "\nStudent ID: ";
    cin >> newStudent.studentID;

    cout << "\nSubject Name: ";
    cin >> newStudent.subjectName;

    for (int i = 0; i < NO_OF_TEST; i++) {
        cout << "\nTest " << i+1 << " mark: ";
        cin >> newStudent.arrayMarks[i];
    }

    return newStudent;
}

int main() {
    studentType s;
    s = input();

    cout <<"\n========"<< endl << "Collected the details of "
        << s.firstName << endl;

    return 0;
}
pevik
  • 4,523
  • 3
  • 33
  • 44
Nandakumar Edamana
  • 770
  • 1
  • 4
  • 10
24

You have a scope problem. Define the struct before the function, not inside it.

Fred Larson
  • 60,987
  • 18
  • 112
  • 174
16

You can now (C++14) return a locally-defined (i.e. defined inside the function) struct as follows:

auto f()
{
    struct S
    {
      int a;
      double b;
    } s;
    s.a = 42;
    s.b = 42.0;
    return s;
}

auto x = f();
a = x.a;
b = x.b;
Rehan
  • 1,299
  • 2
  • 16
  • 19
8
studentType newStudent() // studentType doesn't exist here
{   
    struct studentType // it only exists within the function
    {
        string studentID;
        string firstName;
        string lastName;
        string subjectName;
        string courseGrade;

        int arrayMarks[4];

        double avgMarks;

    } newStudent;
...

Move it outside the function:

struct studentType
{
    string studentID;
    string firstName;
    string lastName;
    string subjectName;
    string courseGrade;

    int arrayMarks[4];

    double avgMarks;

};

studentType newStudent()
{
    studentType newStudent
    ...
    return newStudent;
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • as you are not using `new` operator to create the structure instance, will it be deleted automatically after you call `newStudent()` – Ramesh-X Feb 08 '18 at 10:28
  • 2
    @Ramesh-X No, because `new` creates a *pointer* to an instance created on the heap. If you return the structure directly, it just "copies" (a sufficiently intelligent compiler may just use the location that the caller provided for the returned struct) the bits of the structure into the lvalue that the result of the function call was assigned to in the caller. The problem with returning a local structure arises when you return a "pointer" (the pointer may be a reference, which is not actually required to be implemented using pointers) to the local structure. – cuddlebugCuller Sep 24 '20 at 21:53
-1

As pointed out by others, define studentType outside the function. One more thing, even if you do that, do not create a local studentType instance inside the function. The instance is on the function stack and will not be available when you try to return it. One thing you can however do is create studentType dynamically and return the pointer to it outside the function.

mkny
  • 13
  • 4
  • 7
    If he creates an automatic `studentType` and returns it by copy, the copy constructor will be called (a default one is created if you don't create one), so he will not have any issues. Declaring the structure inside the function is his primary problem - and there is no need to declare it dynamically at present. – Zac Howland Oct 06 '13 at 04:24
  • @ZacHowland AIUI, the default method for returning something from a function is by *move*, not by copy. The callee doesn't need it anymore, after all. – cuddlebugCuller Sep 24 '20 at 21:56
  • 2
    @cuddlebugCuller When the comment was made, that was not the case :) The move semantics have been added and updated a couple times since 2013. – Zac Howland Oct 26 '20 at 04:06