11

Possible Duplicate:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?

$ cat cons.cpp
#include <iostream>

class Matrix {
private:
    int m_count;

public:
    Matrix() {
        m_count = 1;
        std::cout << "yahoo!" << std::endl;
    }
};

int main() {
    std::cout << "before" << std::endl;
    Matrix m1();                         // <----
    std::cout << "after" << std::endl;
}
$ g++ cons.cpp
$ ./a.out
before
after
$

What does the syntax Matrix m1(); do?

I believed that it is the same as Matrix m1;. Obviously I am wrong.

Community
  • 1
  • 1
Lazer
  • 90,700
  • 113
  • 281
  • 364

4 Answers4

12
Matrix m1(); // m1 is a function whose return type is Matrix.

Also this C++ FAQ lite entry should be helpful.

Is there any difference between List x; and List x();

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • 1
    @Lazer: to convince yourself, try to use m1 (for example accessing m1.m_count )... – Francesco Feb 26 '12 at 07:50
  • In C++11 you can use braces for all constructor calls this avoids c++'s most vexing parse i.e Matrix m1{}; – mark Feb 26 '12 at 08:58
  • This isn't the "most vexing parse", the most vexing parse is when you try to declare and object and pass a value initialized temporary to one or more of it's constructor parameters. E.g. `A b(A());`. `Matrix m1();` is just a regular function declaration. – CB Bailey Feb 26 '12 at 09:14
  • @CharlesBailey: the Most Vexing Parse is about treating a declaration as a function declaration if at all possible. This question is indeed just yet another Most Vexing Parse question. – Cheers and hth. - Alf Feb 26 '12 at 10:58
3

Matrix m1() declares a function that takes no parameters and returns a Matrix. You can see this is so by adding a method to Matrix and trying to invoke it on m1:

#include <iostream>

class Matrix {
private:
    int m_count;

public:
    Matrix() {
        m_count = 1;
        std::cout << "yahoo!" << std::endl;
    }
    void foo() {}
};

int main() {
    std::cout << "before" << std::endl;
    Matrix m1();
    m1.foo();
    std::cout << "after" << std::endl;
}

gives error: request for member 'foo' in 'm1', which is of non-class type 'Matrix()'

ibid
  • 3,891
  • 22
  • 17
1

Think from C language perspective:

int data_member();

is actually a prototype for function taking void and returning int. When you change it like:

T data();

it still is a function declaration, retuning T. When you need to declare it as variable, you do:

T data; // int data;
Ajay
  • 18,086
  • 12
  • 59
  • 105
0

This will do what you're trying to do:

int main() {
    std::cout << "before" << std::endl;
    Matrix m1;                         // <----
    std::cout << "after" << std::endl;
}

In C++, if you initialize a variable with parens, it actually declares a function that takes no parameters and returns that type.

Andrew Rasmussen
  • 14,912
  • 10
  • 45
  • 81