-1

I'm new to C++ and I try to adapt a program snippet which generates "weak compositions" or Multisets found here on stackoverflow but I run - to be quite frank - since hours into problems.

First of all, the program runs without any complaint under MSVC - but not on gcc.

The point is, that I have read many articles like this one here on stackoverflow, about the different behaviour of gcc and msvc and I have understood, that msvc is a bit more "liberal" in dealing with this situation and gcc is more "strict". I have also understood, that one should "not bind a non-const reference to a temporary (internal) variable."

But I am sorry, I can not fix it and get this program to work under gcc - again since hours.

And - if possible - a second question: I have to introduce a global variable total, which is said to be "evil", although it works well. I need this value of total, however I could not find a solution with a non-global scope.

Thank you all very much for your assistance.

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int total = 0;

string & ListMultisets(unsigned au4Boxes, unsigned au4Balls, string & strOut = string(), string strBuild = string()) {
  unsigned au4;
  if (au4Boxes > 1) for (au4 = 0; au4 <= au4Balls; au4++)
  {
    stringstream ss;
    ss << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls - au4;
    ListMultisets(au4Boxes - 1, au4, strOut, ss.str());
  }
  else
  {
    stringstream ss;
    ss << mycount << ".\t" << "(" << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls << ")\n";
    strOut += ss.str();
    total++;
  }

return strOut;
}

int main() {
  cout << endl << ListMultisets(5,3) << endl;
  cout << "Total: " << total << " weak compositions." << endl;
  return 0;
}
Community
  • 1
  • 1
  • 2
    What error are you seeing when you compile/run it in gcc? Please include the complete error message in your question. – Dale Wilson Jul 06 '15 at 16:28
  • `string & strOut = string(),` is definitely wrong. Not sure why MSVC allows that. – R Sahu Jul 06 '15 at 16:33
  • 1
    @RSahu MSVC++ has always allowed mutable references to temporaries. Since day 1, I believe. – Drew Dormann Jul 06 '15 at 16:35
  • @DrewDormann, learned something today. – R Sahu Jul 06 '15 at 16:39
  • 1
    @RSahu it is an [old extension](http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug/20851672#20851672) and a similarly surprising extension to [generate an lvalue from a cast](http://stackoverflow.com/a/26508755/1708801) – Shafik Yaghmour Jul 06 '15 at 16:45
  • @ShafikYaghmour, doesn't this question make a duplicate of http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug/20851672#20851672? After all, the source of the issue is the same even though it manifests itself in different ways. – R Sahu Jul 06 '15 at 16:57
  • @RSahu I am not sure what the question is asking actually, although it could be – Shafik Yaghmour Jul 06 '15 at 17:00

2 Answers2

0

Remove the default value for the strOut parameter.

Create a string in main and pass it to the function.

Change the return type of the function to be int.

Make total a local variable ListMultisets(). Return total rather than strOut (you are returning the string value strOut as a reference parameter.)

The signature of the new ListMultisets will look like:

int ListMultisets(unsigned au4Boxes, unsigned au4Balls, string & strOut) 

I'll let you figure out the implementation. It will either be easy or educational.

Your new main function will look like:

int main() {
  string result;
  int total = ListMultisets(5,3, result);
  cout << endl << result << endl;
  cout << "Total: " << total << " weak compositions." << endl;
  return 0;
}
Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
0

C++ demands that a reference parameter to an unnamed temporary (like string()) must either be a const reference or an r-value reference.

Either of those reference types will protect you from modifying a variable that you don't realize is going to be destroyed within the current expression.

Depending on your needs, it could would to make it a value parameter:

string ListMultisets( ... string strOut = string() ... ) {

or it could would to make it a function-local variable:

string ListMultisets(...) {
string strOut;

In your example program, either change would work.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • This is it - the solution for me is to use a function-local variable instead of the unnamed from the parameter list. But I have to make it static, so that now I have: `string & ListMultisets_v2(unsigned au4Boxes, unsigned au4Balls, string strBuild = string()) { static string strOut = string(); ...` – user3832808 Jul 07 '15 at 20:18
  • sorry, but I have problems with this mini-Markdown ... I have to learn this as well. – user3832808 Jul 07 '15 at 20:29