Help: constructor syntax

  • Thread starter =?ISO-8859-1?Q?Christian_Brechb=FChler?=
  • Start date
?

=?ISO-8859-1?Q?Christian_Brechb=FChler?=

I get a compile time error that I don't understand.

======================================= begin constructor.cc ======
struct Negate {};

class A {
int i;
public:
A(double x ): i(int(x)) {}; // 0
A(Negate ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A(Negate, int ii): i( -ii ) {}; // 3
};

void foob(Negate n, int x) {
A a(n,x);
};

template <typename T>

void f() {
A a0(3.0);
A a1(Negate());
A a2(1.4 , 3);
A a3(Negate(), 6); // error
Negate dummy;
A a4(dummy , 6);
A a5 = A(Negate(), 6);
foob(Negate(), 6);
}
======================================= end constructor.cc ======

This gives me two errors on the indicated line. I intend to initialize a3
directly with the third constructor, just like a4 and a (and a5?).

======================================= begin compiler output ======
make -k constructor.o
g++ -c -o constructor.o constructor.cc
constructor.cc: In function `void f()':
constructor.cc:22: type specifier omitted for parameter
constructor.cc:22: parse error before numeric constant
make: *** [constructor.o] Error 1
======================================= end compiler output ======

I'd prefer not to use a dummy object. What is the correct syntax? And what does
the error try to tell me?

Thanks

Christian
 
J

Josephine Schafer

Christian Brechbühler said:
I get a compile time error that I don't understand.

======================================= begin constructor.cc ======
struct Negate {};

class A {
int i;
public:
A(double x ): i(int(x)) {}; // 0
A(Negate ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A(Negate, int ii): i( -ii ) {}; // 3
};

void foob(Negate n, int x) {
A a(n,x);
};

template <typename T>

void f() {
A a0(3.0);
A a1(Negate());
A a2(1.4 , 3);
A a3(Negate(), 6); // error
Negate dummy;
A a4(dummy , 6);
A a5 = A(Negate(), 6);
foob(Negate(), 6);
}
======================================= end constructor.cc ======

This gives me two errors on the indicated line. I intend to initialize a3
directly with the third constructor, just like a4 and a (and a5?).

======================================= begin compiler output ======
make -k constructor.o
g++ -c -o constructor.o constructor.cc
constructor.cc: In function `void f()':
constructor.cc:22: type specifier omitted for parameter
constructor.cc:22: parse error before numeric constant
make: *** [constructor.o] Error 1
======================================= end compiler output ======

I'd prefer not to use a dummy object. What is the correct syntax? And what does
the error try to tell me?

Thanks

I made a quick glance through your code and the most apparent mistake is that
there should be no semicolon after function definitions.
i.e. A(double x ): i(int(x)) {}; // 0
should be A(double x ): i(int(x)) {} //No semicolon after braces.

Try that out.

HTH,
J.Schafer
 
C

Chris Theis

Josephine Schafer said:
Christian Brechbühler said:
I get a compile time error that I don't understand.
[SNIP]
I'd prefer not to use a dummy object. What is the correct syntax? And
what
does
the error try to tell me?

Thanks

I made a quick glance through your code and the most apparent mistake is that
there should be no semicolon after function definitions.
i.e. A(double x ): i(int(x)) {}; // 0
should be A(double x ): i(int(x)) {} //No semicolon after braces.

Try that out.

HTH,
J.Schafer

As long as the implementation is done directly inside the class where the
functions are defined, then the extra semicolons do no harm.

But this piece of code is troublesome 'cause here the OP should skip the
trailing semicolon after the end of scope brace. Although some compilers
(MSVC for example) will dump the semicolon silently.

To the OP:

Instead of using a dummy struct, why don't you use a enumerated flag to
indicate the operation. For example:

class A {
int i;
public:
enum Operation { Negate, Multiply };
A(double x ): i(int(x)) {}; // 0
A( ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A( Operation, int ii): i( -ii ) {}; // 3
};

void foob( A::Operation n, int x) {
A a(n,x);
}

template <typename T>
void f() {
A a0(3.0);
A a1( A::Negate );
A a2(1.4 , 3);
A a3( A::Negate, 6); // error
A a5 = A( A::Negate , 6);
foob( A::Negate, 6);
}

HTH
Chris
 
K

Karl Heinz Buchegger

Christian said:
I'd prefer not to use a dummy object. What is the correct syntax? And what does
the error try to tell me?

I am not sure why the compiler emits that errors, It looks ok to me.
But then you should get into the habit of accepting class objects per
const reference instead of per value.

Try:

class A {
int i;
public:
A(double x ): i(int(x)) {}; // 0
A( const Negate & ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A(const Negate &, int ii): i( -ii ) {}; // 3
};
 
J

Josephine Schafer

Chris Theis said:
Josephine Schafer said:
Christian Brechbühler said:
I get a compile time error that I don't understand.
[SNIP]
I'd prefer not to use a dummy object. What is the correct syntax? And
what
does
the error try to tell me?

Thanks

I made a quick glance through your code and the most apparent mistake is that
there should be no semicolon after function definitions.
i.e. A(double x ): i(int(x)) {}; // 0
should be A(double x ): i(int(x)) {} //No semicolon after braces.

Try that out.

HTH,
J.Schafer

As long as the implementation is done directly inside the class where the
functions are defined, then the extra semicolons do no harm.
True..my bad .
But this piece of code is troublesome 'cause here the OP should skip the
trailing semicolon after the end of scope brace. Although some compilers
(MSVC for example) will dump the semicolon silently.
yes..this ofcourse is still an error.
 
?

=?ISO-8859-1?Q?Christian_Brechb=FChler?=

Chris said:
that there should be no semicolon after function definitions.

As long as the implementation is done directly inside the class where the
functions are defined, then the extra semicolons do no harm.

I confirm that dropping the semicolons makes no difference
But this piece of code is troublesome 'cause here the OP should skip the
trailing semicolon after the end of scope brace. Although some compilers
(MSVC for example) will dump the semicolon silently.

No difference here either (gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)).
To the OP:

Instead of using a dummy struct, why don't you use a enumerated flag to
indicate the operation. For example:

class A {
int i;
public:
enum Operation { Negate, Multiply };
A(double x ): i(int(x)) {}; // 0
A( ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A( Operation, int ii): i( -ii ) {}; // 3
};

void foob( A::Operation n, int x) {
A a(n,x);
}

template <typename T>
void f() {
A a0(3.0);
A a1( A::Negate );
A a2(1.4 , 3);
A a3( A::Negate, 6); // error
A a5 = A( A::Negate , 6);
foob( A::Negate, 6);
}

Yes, this works, thanks! I'm going to use this solution. To answer "why not an
enum" -- in case I wanted the Multiply, I would put the factor in as a member.

I gather that the error with A(Negate(), 6) is spurious, i.e., may be a compiler bug?

Thanks again

Christian
 
?

=?ISO-8859-1?Q?Christian_Brechb=FChler?=

Karl said:
I am not sure why the compiler emits that errors, It looks ok to me.
But then you should get into the habit of accepting class objects per
const reference instead of per value.

Try:

class A {
int i;
public:
A(double x ): i(int(x)) {}; // 0
A( const Negate & ): i(-1 ) {}; // 1
A(double, int ii): i(4*ii ) {}; // 2
A(const Negate &, int ii): i( -ii ) {}; // 3
};


Thanks for confirming it looks right. Maybe it's a compiler bug.

I am in the habit of passing objects by reference. In this particular case
however, sizeof(Negate) = 0, and the size of the reference is 4 bytes. So I chose
the smaller, passing by value.
For the syntax sake, I changed my code using your suggestion:

struct Negate {};

class A {
int i;
public:
A(int ii) : i( ii) {}
A(const Negate&, int ii): i(-ii) {}
};

void f() {
A a0(3);
A a3(Negate(), 6); // error
}

Unfortunately, the error is unchanged. The closest to an "no-operation" operator
I found in C++ is *& -- as in, A a3(*&Negate(), 6). That gets rid of the error,
but gives me a warning for taking the address of a temporary.

I'll go with the enum solution proposed by Karl-Heinz Buchegger.

Thanks again

Christian
 
J

jeffc

Christian Brechbühler said:
Thanks for confirming it looks right. Maybe it's a compiler bug.

I am in the habit of passing objects by reference. In this particular case
however, sizeof(Negate) = 0, and the size of the reference is 4 bytes. So I chose
the smaller, passing by value.

OK, but sizeof(Negate) should not be 0. Have you actually checked it?
 
?

=?ISO-8859-1?Q?Christian_Brechb=FChler?=

jeffc said:
I chose



OK, but sizeof(Negate) should not be 0. Have you actually checked it?

No, I hadn't. I assumed, because normally, a plain class/struct's size is the sum
of the data members, except for alignment.

You are absolutely right. I checked, and the size is 1 (still less than 4).

Thanks for catching this!

Christian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top