0
#include<iostream>

class Foo
{
public:
    int qux(int x);
};

int Foo::qux(int x)
{
    return 2 * x;
}

int main()
{
    Foo foo();
    int a = foo.qux(4);
}

displays the error

Error : expression must have class type but it has type "Foo (*)()"

It would work if I don't use the parenthesis when instantiating foo. But it should also instantiate the object with parenthesis at the end right? Why does it create a function pointer?

roi_saumon
  • 489
  • 4
  • 13
  • Congratulations on hitting the Most Vexing Parse (as the duplicate explains more). Also investigate [Uniform Initialization](https://isocpp.org/wiki/faq/cpp11-language#uniform-init) since that's what you want for your objects. Welcome to C++. – Kevin Anderson Sep 19 '22 at 13:03
  • @KevinAnderson, thanks for the reference, vexing indeed – roi_saumon Sep 19 '22 at 13:08
  • 1
    @KevinAnderson “Uniform” is a lie (due to initialiser lists) and many C++ experts consider it a mistake in hindsight. It certainly won’t avoid initialisation fubar, so I no longer use (nor recommend) it universally. Instead, I now advocate for “always auto”. It’s the best way in C++ of avoiding unexpected initialisation behaviour. – Konrad Rudolph Sep 19 '22 at 13:14
  • @KonradRudolph Oh I absolutely agree that the name is a misnomer, but "starting from there" is a rather good thing IMO, and like it or not, "Uniform" is in the "official" name of that. Start with a generally OK thing, then finding out its limitations is a decent way to learn. The virtues of "always auto" are many, but it also has drawbacks that make it not "universal" either, but that's a different topic. – Kevin Anderson Sep 19 '22 at 13:44
  • @KevinAnderson actually I think I was confused because of the notation `MyClass* object = new MyClass();` which create a pointer to an object initialized to zero – roi_saumon Sep 19 '22 at 13:59
  • @KevinAnderson The issue with “starting from there” is that it does the wrong/unexpected thing by default. For instance, you *must not* use uniform initialisation with generic code (`T{args}`) unless you actually want to invoke the initialiser list constructor. That’s why I’ve reverted to using `()` by default: it always works, does the correct/expected thing, and with Always Auto it never triggers MVP. – Konrad Rudolph Sep 19 '22 at 14:59

0 Answers0