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) };
}

3 Answers 3

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} };
Sign up to request clarification or add additional context in comments.

2 Comments

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?
@AnasAyubi 980 and 1100 are both ints, so integer division occurs rather than floating point division. You probably want something like 980.0/1100.
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.

4 Comments

What do you mean by a temporary?
student(/*...*/) creates a temporary object which is used to populate the array by copying it.
Isn't that a really inefficient way of storing objects in an array? Can we avoid the copying somehow?
It would be if we didn't have copy elision, which will prevent the copying for you.
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.