Attempt at initialising a class with a vector "inline"

  • Thread starter =?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=
  • Start date
?

=?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=

Hello all!

I am trying to write code that allows me to initialise one of my classes
inline (with a vector like structure). Inline might not be the best
term to use here but I can't think of any other right now. Here is my code:

template <typename T>
class Array {
public:
Array& operator()(const T& v) {
a.push_back(v);
return *this;
}

Array& foo(const T& v) {
return *this;
}

private:
std::vector<T> a;
};

class M {
public:
M(const Array<char>&) { }
};

int main() {
M m(Array<char>()(0)(1)(2)(1)); // XXX
return 0;
}

At the line marked with XXX you can see what I want to accomplish. My
problem is that this won't compile. However, if I call Array::foo()
instead of operator() it compiles fine. This confuses me. Maybe someone
on this list can enlighten me as to what is happening.

Regards,
Mattias
 
B

bartek

Hello all!

I am trying to write code that allows me to initialise one of my
classes
inline (with a vector like structure). Inline might not be the best
term to use here but I can't think of any other right now. Here is my
code:

template <typename T>
class Array {
public:
Array& operator()(const T& v) {
a.push_back(v);
return *this;
}

Array& foo(const T& v) {
return *this;
}

private:
std::vector<T> a;
};

class M {
public:
M(const Array<char>&) { }
};

int main() {
M m(Array<char>()(0)(1)(2)(1)); // XXX
return 0;
}

At the line marked with XXX you can see what I want to accomplish. My
problem is that this won't compile. However, if I call Array::foo()
instead of operator() it compiles fine. This confuses me. Maybe
someone on this list can enlighten me as to what is happening.

Do you really believe that "someone on this list" has a crystal ball or
something, and can magically see what error messages are you getting?

Btw. the code above compiles without any errors for me. -- Now, please
would you magically guess what compiler I'm using?

Cheers.
 
?

=?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=

bartek said:
Do you really believe that "someone on this list" has a crystal ball or
something, and can magically see what error messages are you getting?

Btw. the code above compiles without any errors for me. -- Now, please
would you magically guess what compiler I'm using?

My bad.

The compiler I'm using is gcc 3.3.3 and the error message looks like this:

foo.cpp: In function `int main()':
foo.cpp:25: error: syntax error before numeric constant
foo.cpp:25: error: function `M m(...)' is initialized like a variable
foo.cpp:25: error: invalid declarator
foo.cpp:25: error: invalid declarator
foo.cpp:25: error: syntax error before `)' token

:.:: mattias
 
B

bartek

The compiler I'm using is gcc 3.3.3 and the error message looks like
this:

foo.cpp: In function `int main()':
foo.cpp:25: error: syntax error before numeric constant
foo.cpp:25: error: function `M m(...)' is initialized like a variable
foo.cpp:25: error: invalid declarator
foo.cpp:25: error: invalid declarator
foo.cpp:25: error: syntax error before `)' token

It's most probably a gcc bug. The code gets compiled smoothly with Comeau
Online, and M$VC++ 2003.

Sorry.
 
R

Rob Williscroft

Mattias Brändström wrote in in
comp.lang.c++:
Hello all!

I am trying to write code that allows me to initialise one of my
classes
inline (with a vector like structure). Inline might not be the best
term to use here but I can't think of any other right now. Here is my
code:

#include <vector>

Please post compilable snippets when possible.
template <typename T>
class Array {
public:
Array& operator()(const T& v) {
a.push_back(v);
return *this;
}

Array& foo(const T& v) {
return *this;
}

private:
std::vector<T> a;
};

class M {
public:
M(const Array<char>&) { }
};

int main() {
M m(Array<char>()(0)(1)(2)(1)); // XXX

This is the initialization as function declaration problem, aka
"C++'s most vexing parse" fix it with:

M m = Array<char>()(0)(1)(2)(1);

Here's another example:

int i( int() );

This is parsed as:

int i( int (*)( void ) );

I.e. a declaration of a function taking function pointer
and retuning int.

Your example simplified:

M m( Array()( XXX ) );

The compiler tries to parse this as (someting like):

M m( Array (*)(*)( void )( XXX ) );

I.e. a function 'm' that returns an 'M' and takes a function
pointer to a function that returns a function-pointer (*).

When it sees XXX it expects a paramiter declaration, but gets a
literal 0, so you get the "compile time constant" error message.

*) I'm actually just Guessing here, nobody in there right mind
would intentionaly write code like this.

The point is that even though I can't make any sense of it
the compiler at least tries too :).

HTH.

Rob.
 
B

bartek

This is the initialization as function declaration problem, aka
"C++'s most vexing parse" fix it with:

M m = Array<char>()(0)(1)(2)(1);

Here's another example:

int i( int() );

This is parsed as:

int i( int (*)( void ) );

I.e. a declaration of a function taking function pointer
and retuning int.

Your example simplified:

M m( Array()( XXX ) );

The compiler tries to parse this as (someting like):

M m( Array (*)(*)( void )( XXX ) );

I.e. a function 'm' that returns an 'M' and takes a function
pointer to a function that returns a function-pointer (*).

When it sees XXX it expects a paramiter declaration, but gets a
literal 0, so you get the "compile time constant" error message.

*) I'm actually just Guessing here, nobody in there right mind
would intentionaly write code like this.

The point is that even though I can't make any sense of it
the compiler at least tries too :).

At least Comeau and M$VC++ 2003 make enough sense of it to compile the
following code. Note the additional method call in main() to check what
actually got recognised is really an instantiation of the class.

Unfortunately, it seems GCC is not smart enough (yet)...

#include <vector>

template <typename T>
class Array {
public:
Array& operator()(const T& v) {
a.push_back(v);
return *this;
}
private:
std::vector<T> a;
};

class Test {
public:
Test(const Array<char>&) { }
void blah() const { }
};

int main() {
Test t( Array<char>()(0)(1)(2)(1) );
t.blah();

return 0;
}
 
R

Rob Williscroft

bartek wrote in in
comp.lang.c++:
#include <vector>

template <typename T>
class Array {
public:
Array& operator()(const T& v) {
a.push_back(v);
return *this;
}
private:
std::vector<T> a;
};

class Test {
public:
Test(const Array<char>&) { }
void blah() const { }
};

int main() {
Test t( Array<char>()(0)(1)(2)(1) );
t.blah();

return 0;
}

Yep you are correct, for the record gcc 3.4 compiles fine too,
though gcc 3.2 doesn't.

Really confused as to how I got my previous results, as I was
puting the code through 4 different compilers :(.

Bizzarly gcc 3.2 doesn't handle:

M m = (Array<char>()(0)(1)(2)(1));

But does handle:

M m = Array<char>()(0)(1)(2)(1);

Rob.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top