2

I realize this isn't necessarily something you would want to do, but I ran into some code similar to this the other day. So, I want to look into the idea a bit more...

I have a class that has overloaded a constructor and a functor. This works as expected. However, when you call a class with the default constructor and then try to use the functor, it fails (because it can't figure out how to convert the class to an int, which isn't what I would want, anyhow.) What would be the correct way of doing this?

#include <cstdio>

class foo
{
public:
    foo(int a, int b);
    foo();
    int operator()();
private:
    int result;
};

foo::foo(int a, int b)
{
    printf("I am a foo(int, int). a: %d b: %d\n", a, b);
    result = a + b;
}

foo::foo()
{
    printf("I am a base foo!\n");
    result = -1;
}

int foo::operator()()
{
    return result;
}

int main(void)
{
    int ret1 = -12345;
    int ret2 = -12345;

    foo myfoo(3, 8);
    foo otherfoo();

    ret1 = myfoo();
    ret2 = otherfoo(); //fails. Also, otherfoo()() fails.

    printf("foo: %d otherfoo: %d\n", ret1, ret2);

return 0;
}
Maxthecat
  • 1,250
  • 17
  • 37

2 Answers2

8

Surprisingly, the

foo otherfoo();

declares a function and not an object. See C++ Gotchas (Gotcha #19: Function/Object Ambiguity) for a discussion.

To fix, change that line to

foo otherfoo;

or, in C++11, to

foo otherfoo{};
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 2
    Or `foo otherfoo{};` in C++11 – Brian Bi Feb 24 '14 at 19:51
  • Thanks @BrianBi. I've added that to the answer. – NPE Feb 24 '14 at 19:53
  • 1
    NPE, that link is very very very susceptible to link rot. There is already a lot of good discussion on [C++'s most vexing parse](http://stackoverflow.com/questions/16588750/cs-most-vexing-parse-again) right here on SO. – Nicu Stiurca Feb 24 '14 at 20:04
0

There is an ambiguiuty between function declarations and object definitions. They have the same syntax. So it was decided to consider this syntax as a function declaration. Thus in this statement

foo otherfoo();

there is a function declaration that have return type foo and does not accept arguments.

To define an object of a class using the default constructor and at the same time zero-initialize its members you can use the following syntax

foo otherfoo {};
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335