2

From the code below being compiled in CodeBlocks I'm getting errors of the this type:

 no matching function for call to 'student::student(student)' candidates are:
 student::student(student&)
     no known conversion for argument 1 from 'student' to 'student&'
 student::student(std::string, int, double, float)
     candidate expects 4 arguments, 1 provided

I'm guessing that somehow the C++ compiler is implementing the copy constructor in the array definition. But I can't seem to find a way around it. I need both constructors in my program and I need to initialize the array elements through a constructor. Please provide a solution that will work on C++11.

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

class student{
    string name;
    int rollno;
    double marks;
    float per;
    /// Constructors
    student(string n, int r, double m, float p){
        name = n;
        rollno = r;
        marks = m;
        per = p;
    }
    student(student& s){
        name = s.name;
        rollno = s.rollno;
        marks = s.marks;
        per = s.per;
    }
};

int main(){
    student arrays[] = { student("Anas Ayubi", 80, 980, 980/1100),
                    student("Zainab Ashraf", 78, 990, 990/1100 ),
                    student("Wali Ahmed", 28, 890, 890/1100) };
}
Anas Ayubi
  • 227
  • 1
  • 3
  • 9

3 Answers3

4
student(student& s){

Your copy constructor takes its argument by non-const reference. Non-const references cannot bind to rvalues. You then go on to try and create copies of rvalues:

student arrays[] = { student("Anas Ayubi", 80, 980, 980/1100),
                student("Zainab Ashraf", 78, 990, 990/1100 ),
                student("Wali Ahmed", 28, 890, 890/1100) };

The easy fix for this is to declare the copy constructor to take a reference-to-const, which can bind to rvalues:

student (const student& s){

Note that in 980/1100 you get integer division instead of floating point division, so you'll just get 0. To fix this, force those ints to be doubles: 980.0/1100.

Incidentally, in C++11 you can simplify your array initialization like so:

student arrays[] = { {"Anas Ayubi", 80, 980, 980.0/1100},
                     {"Zainab Ashraf", 78, 990, 990.0/1100},
                     {"Wali Ahmed", 28, 890, 890.0/1100} };
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • Thank you for the great answer!! When I try to display the 'per' field in the program of elements in the array, it displays the value 0. Why is that happening? – Anas Ayubi Aug 18 '15 at 13:05
  • @AnasAyubi `980` and `1100` are both `int`s, so integer division occurs rather than floating point division. You probably want something like `980.0/1100`. – TartanLlama Aug 18 '15 at 13:07
2

It should be student(const student& s) - note the const - the proper signature of a copy constructor.

This is because you're attempting to bind temporaries to references, in which case const references are required.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

Your copy constructor should take its parameter by const reference, so it can bind to the temporaries you provide.

Quentin
  • 62,093
  • 7
  • 131
  • 191