3

I'm implementing a thread-safe singleton. But this aspect (singleton & thread-safe) is not part of my question.

Compare the two codes. Code 1:

#include <iostream>
using namespace std;
class DataLocation {
private:
  DataLocation(std::string) {
  }
public:
  DataLocation& getInstance() {
    std::string s = " ";
    static DataLocation instance(s);
    return instance;
  }
};
int main() {
}

and code 2:

#include <iostream>
using namespace std;
class DataLocation {
private:
  DataLocation() {
  }
public:
  DataLocation& getInstance() {
    static DataLocation instance();    
    return instance;
  }
};
int main() {
}

Code 1 compiles fine. Code 2 gives the following error:

15_singleton.cpp: In member function ‘DataLocation& DataLocation::getInstance()’:
15_singleton.cpp:15:34: error: cannot declare static function inside another function
     static DataLocation instance();    
                                  ^
15_singleton.cpp:16:12: error: invalid initialization of non-const reference of type ‘DataLocation&’ from an rvalue of type ‘DataLocation (*)()’
     return instance;
            ^

From my point of view the only difference is that the private constructor has one, respectively zero parameters.

How can I help the compiler to understand that I'm not defining anything new, but I'm just calling the constructor? The compiler is able to understand it, when there is one parameter.

PeptideChain
  • 543
  • 3
  • 16

4 Answers4

5

Remove the brackets

static DataLocation instance; 

To create the instance with the default constructor.

Alternatively, use the braced form of initialisation.

static DataLocation instance {};
Niall
  • 30,036
  • 10
  • 99
  • 142
Sebastian Hoffmann
  • 2,815
  • 1
  • 12
  • 22
2
static DataLocation instance = DataLocation(); 

or

static DataLocation instance;

And you would probably want to declare DataLocation& getInstance(); as a static method.

Teivaz
  • 5,462
  • 4
  • 37
  • 75
  • 4
    Not sure why you would want the first version. Especially as, for a singleton, you usually disable the copy constructor so the first version should not compile. – Galik May 16 '16 at 10:11
2

You are using brackets () while declaring

static DataLocation instance(); 

which you intent to create as an object. But is, simply a function declaration. And you cannot create a static function inside some other non-static function. That is what your error refers to.

Fahad Siddiqui
  • 1,829
  • 1
  • 19
  • 41
1

Method getInstance() should be declared as a static.

Radek
  • 518
  • 5
  • 12
  • I would also define it static, but I used this [model](http://stackoverflow.com/a/19907903), and the model got +33...and I'm a beginner – PeptideChain May 16 '16 at 09:58
  • @Niall: There is no ambiguity. Surprise for some? Sure. But by definition there is no ambiguity. BTW, the most vexing parse relates to `A a(B());`. It's caused by the same language rules as a novice's surprise after using the wrong declarator syntax. – Lightness Races in Orbit May 16 '16 at 10:38
  • 1
    @LiPo: I did't downvote, but while Radek is right, it doesn't answer the question. – MikeMB May 16 '16 at 10:56