1

apologies if this answer should be obvious, perhaps this has a pattern name like "dopey assignment overload" and have not been searching by right topic - redirects most welcome code extracts:

class MySet {
        private:
                int lower;
                int upper;
                char *data;
        public:
                MySet( int l, int u, const char *val = 0 );

                MySet &operator=( MySet &rhs );
                MySet &operator=( const char *val );
};

int main(int i, const char *argv[])
{
        MySet A(1,10);
        A = "hello";

        MySet B(1,10, "hello");
        MySet C(1,10) = "hello";

}

assignments for A and B work but for C then g++ whines....: myset.cxx:19:16: error: expected ‘,’ or ‘;’ before ‘=’ token

is not a big issue but have been trying to understand why is not valid.

thanks for any helpful replies.

more info... guess am meant to edit my op?

on puzzling out why the above is considered illegal, have been looking for a definitive reason ... and of course a trick to make such notation be accepted by the compiler.

considering the similar uses that are legal

struct toons {
     char first[10];
} flintstone[] = {
     "fred",
     "wilma",
     ""
};

works from couple decades of C compilers, as does:

typedef struct {
    char family[10];
    struct {
            char name[10];
    } members[6];
} toongroup;

toongroup rubble = {
    "rubble",
    {
            "barney",
            "wilma",
            ""
    }
}

toongroup rubble = {
    "rubble",
    {
            "barney",
            "wilma",
            "", "", "", ""
    }
};

toongroup jetsons = { "jetson", { "george", "jane", "", "", "", "" } };

all honored by c++ compilers. can have member functions on the structure and it still works:

typedef struct toongroup {
    public:
            bool add( const char *newbaby ) {
                    for(int i; i<6; i++) {
                            if(strlen(members[i].name) == 0) {
                                    strcpy(members[i].name, newbaby);
                                    return true;
                            }
                            if(strcmp(members[i].name, newbaby) == 0)
                                    return false;
                    }
                    return false;
            }
    char family[10];
    struct {
            char name[10];
    } members[6];
} toongroup;

toongroup jetsons = { "jetson", { "george", "jane", "", "", "", "" } };

jetsons.add( "elroy" );

objections start when adding a constructor:

typedef struct toongroup {
    toongroup( const char *f, const char *m, ... ) {
    }


error: in C++98 ‘rubble’ must be initialized by constructor, not by ‘{...}’
error: could not convert ‘{"rubble", {"barney", "wilma", "", "", "", ""}}’ from ‘<brace-enclosed initializer list>’ to ‘toongroup‘

wondering if it could be a matter of using the right initializer so compiler can match the constructor

    toongroup empty;
    toongroup nobody = empty;
    toongroup rubble( "rubble", "barney", "wilma", "" );

even

    toongroup empty;
    toongroup cancelled;
    toongroup nobody = empty;
    toongroup rubble( "rubble", "barney", "wilma", "" );
    toongroup jetsons( "jetson", "george", "jane", "" );

    jetsons.add( "elroy" );

adding

    toongroup &operator=( toons &t );

allows

    jetsons = cancelled;

but not

    toongroup jetsons( "jetson", "george", "jane", "" ) = cancelled;

apologies for this ending up a long post, but am looking for some reference as to why the constructor + assignment is rejected and any ideas on how/if this can be accommodated.

in the notation for MySet this would be a familiar statement, before i declared it illegal wanted to check if am missing a trick.

thanks.

Artem Zankovich
  • 2,319
  • 20
  • 36
chaosless
  • 573
  • 5
  • 8

3 Answers3

3

Because

MySet C(1,10) = "hello";

is illegal. You can't call assignment or anything else when you initialize a variable.

If it did work, the = would stand for initialization, not assignment.

Just like:

int x = 5;  //initialization, not assignment

is equivalent to

int x(5);

and not

int x;
x = 5;
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • That is, the initalization syntax uses only copy constructor. – Israel Unterman Apr 30 '12 at 08:34
  • Well, the last three snippets are all equivalent. In general, though, no pair of the three snippets is equivalent (the first requires an accessible copy constructor, the second does not). – avakar Apr 30 '12 at 08:53
  • but in some cases a constructor and assignment can live on the same line - added to my OP toongroup nobody = empty this calls the default constructor and then the assignment operator, without complaint? – chaosless Apr 30 '12 at 18:49
  • @chaosless no. And please don't drastically edit your questions. The answers become obsolete if you do. Ask a new question. – Luchian Grigore Apr 30 '12 at 18:50
  • @chaosless the extra info you posted is completely different. You first initialize an array, which is legal. Second, you call `operator=` on an existing object, as opposed to here, where you create the object on the same line. – Luchian Grigore Apr 30 '12 at 19:46
  • yes, posted my steps in exploring why the syntax is valid when it involves only the default constructor and assignment on the same line. my question was why having constructor and assignment on same line becomes illegal with non-default constructor and if am missing a trick to allow the compound statement. – chaosless Apr 30 '12 at 20:45
  • what is the preferred way to add more information to a question? only option i saw was to put comments in these tiny 500 character boxes... what did i miss? – chaosless Apr 30 '12 at 20:46
  • @chaosless as I said before, ask a new question. And reduce your samples to the minimum. – Luchian Grigore Apr 30 '12 at 20:47
  • new question that is old question plus some comments seems like wasted traffic - already spent time making the question usable - in what way was it verbose? i'd like to participate here, but if the question fits in a few lines then is very doubtful i'd need to ask it. – chaosless Apr 30 '12 at 21:55
  • @chaosless there's a lot of noise - methods that aren't used, unneeded strings, big indentation tabs, etc. It can be reduced to 7-8 lines of code. And you need to learn how to separate the issues - what's this `if(strcmp(members[i].name, newbaby) == 0) return false;` does it have anything to do with the question? – Luchian Grigore Apr 30 '12 at 21:57
1

The problem is that when you write:

MySet C = "hello";

Actually the constructor from character array is invoked (if such existed), not the assignment operator. Thus with your code you confuse the compiler: which of two constructors to call.

Basically equality on the declaration row is converted to constructor call. From then on the assignment operators are used.

Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135
0

Remember 2 points:

  1. When a variable is declared, the subsequent = is not an assignment operator, but rather meant for construction of the object.
  2. C++ compiler allows only 1 constructor at a time.

Keeping those in mind, look at the problematic code:

MySet C(1,10) = "hello";

This declares and object of MySet and constructs it with (1,10).
Now there is no point of having another construction using = "hello" which would overpower the existing construction.
That's why the error.

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • added to my OP toongroup nobody = empty which calls the default construct and the assignment operator ... – chaosless Apr 30 '12 at 18:51
  • and **there is a point to having this notation** or i'd not ask the question ... MySet is an array - with bounds (1,10) - and an initial value of "hello" is a very natural way to write such a declaration, so am exploring if it can be made legal before telling my developers it is impossible. – chaosless Apr 30 '12 at 18:54
  • and i do have a constructor MySet( int lower, int upp, const char *initial = NULL ) that could be used, just trying to figure out if there is another option – chaosless Apr 30 '12 at 18:55