0

For the code below, static SortOfSingleton instance; works, but static SortOfSingleton instance(); creates four compilation errors:

  • a block-scope function may only have extern storage class
  • a reference of type "SortOfSingleton &" (not const-qualified) cannot be initialized with a value of type "SortOfSingleton ()"
  • 'instance': static functions with block scope are illegal
  • 'return': cannot convert from 'SortOfSingleton (__cdecl *)(void)' to 'SortOfSingleton &'

I do not understand those error messages. Isn't static SortOfSingleton instance(); creating a new instance by calling the empty constructor declared above? I wondered if I must not use () when assigning a reference, but there seems to be code that uses it, so that is probably not that.

What is the difference between instance(); and instance; below?

Code:

class SortOfSingleton
{
public:
    static SortOfSingleton& getInstance();
private:
    SortOfSingleton();
    SortOfSingleton(const SortOfSingleton&) = delete;
    SortOfSingleton& operator=(const SortOfSingleton&) = delete;
};

SortOfSingleton::SortOfSingleton()
{
    std::cout << "Creating new instance."<< std::endl;
}

SortOfSingleton& SortOfSingleton::getInstance()
{
    static SortOfSingleton instance;
    //static SortOfSingleton instance();
    return instance;
}

int main()
{
    auto& instance1 = SortOfSingleton::getInstance();
Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135
  • It's the same as the difference between `int x;` and `int x()`. One is an integer variable, the other one is a function that returns an integer. – Sam Varshavchik Nov 22 '21 at 19:10
  • Looks like a most vexing parse. It'd probably work with `static SortOfSingleton instance{};` – scohe001 Nov 22 '21 at 19:10
  • 1
    @scohe001 -- it's certainly vexing for beginners, but it is not the [most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse). – Pete Becker Nov 22 '21 at 19:18
  • @Pete from the wiki you linked "*the C++ grammar cannot distinguish between the creation of an object parameter and specification of a function's type. In those situations, the compiler is required to interpret the line as a function type specification.*" that sounds like about what's happening here. And the top answer on the dupe I linked agrees as well. Am I misreading these? – scohe001 Nov 22 '21 at 19:20
  • @scohe001 -- the meaning of `int f()` is trivial to understand, once it's been explained. The examples in the page that I linked to are not so simple to understand. You're right that they're all the result of that rule, but they're not all equally vexing. – Pete Becker Nov 22 '21 at 19:38
  • An answer in the linked page says "Since () is not permitted by the syntax for initializer", so I cannot use () only when the constructor has no argument, is that right? – Damn Vegetables Nov 22 '21 at 19:41
  • "*only when the constructor has no argument, is that right?"* - No. The most vexing parse page has a few examples. – StoryTeller - Unslander Monica Nov 22 '21 at 19:44
  • @StoryTeller-UnslanderMonica But I just tested it by changing it to `private: SortOfSingleton(int a);`, `SortOfSingleton::SortOfSingleton(int a)`, and ` static SortOfSingleton instance(123);`, and it was compiled without errors. – Damn Vegetables Nov 22 '21 at 19:48
  • I quite clearly mentioned there are cases where this won't work. My objection was to your (wrong) generalisation. It's not only the "no arguments" case that is prone to break. – StoryTeller - Unslander Monica Nov 22 '21 at 19:50

0 Answers0