Question

This may be hard to explain. There's this snippet of code:

void user_choice(string f) {
    bool goodchoice;
    string file = f;
    while (!goodchoice) {
        string answer;
        cin >> answer;

        if (answer == "save") {
            Data(file, "05/05/2014");
            goodchoice = true;
        }
        else if (answer == "look") {
            Data(file);
            goodchoice = true;
        }
        else cout << "I don't understand that. Please try again." << endl;
    }
}

I have a class called Data with these constructors:

Data(string n);
Data(string n, string d);

I included the Data.h header file in my main CPP file. The if-statement for 'save' works fine, but the if-statement for 'look' tells me that there is no default constructor for Data even though there is. I am using Visual Studio 2013.

Was it helpful?

Solution

Data(file);

This is not calling the constructor taking a string. Instead, it's declaring an object of Data named file and using the default constructor to do it. It's the same thing as:

Data file;

I can't remember 100% why this behaviour exists, but I believe it was inherited from C. You should be able to find more examples of this by relating it to the Most Vexing Parse, as this happens quite a bit in relation to that.

Funnily enough, this isn't one of those situations where you can fix it by adding another set of parentheses. I am unaware of the accepted method of making this call the constructor (probably for the better, as noted below), but casting is one option, and calling a function another, though both seem unnatural:

Data((file)); //doesn't work
Data(static_cast<string>(file)); //works
(void)Data(file); //works

template<typename T>
T &self(T &arg) {
    return arg;
}

Data(self(file)); //works

Unless the constructors have side effects, these will not do anything meaningful, just create and destroy an object. I'm honestly not sure what these statements are meaning to accomplish. If the constructor is responsible for performing an action and you only need temporary objects, make Data a function instead. If you want to use the instance to call a member function on it or similar, you should store the instance in a variable so you can use that variable to do what it needs to do. The above "fixes" should all be shallow workarounds to a deeper problem.

OTHER TIPS

Data is a class,not an object. So,Data(file) calling a copy construct function.And you don't declare a copy construct function.you need declare a object like Data data and data(file)

You need one of two things... one of these two constructors

Data();
//or
Data(string n = "default argument here");

You are also making an error when you say Data(file); because you are creating a temporary object of type "Data" by calling the constructor but you are not storing it. I think you are tying to do this.

void user_choice(string f) {
    bool goodchoice;
    Data myData;//this requires the constructors i listed above
    string file = f;
    while (!goodchoice) {
        string answer;
        cin >> answer;

        if (answer == "save") {
            //assign to data by calling the constructor
            myData=Data(file, "05/05/2014");
            goodchoice = true;
        }
        else if (answer == "look") {
            //assign to data by calling the constructor
            myData=Data(file);
            goodchoice = true;
        }
        else cout << "I don't understand that. Please try again." << endl;
    }
}

I believe this should fix your problem. Good Luck

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top