0

I'm making class, that should help with minor deficiencies of C++, like comparing double with other double with defined precision, and so on.

I have namespace Utilities, where class Double exists:

namespace Utilities {

void init();

class Double {
public:
    //! @brief Compares the equality of two doubles with defined precision
    static bool fuzzyCompare(const double &d1,const double &d2);

    static void setFuzzyComparePrecision(int precision);
private:
    //! @brief Private constructor
    Double() {};

    static int fuzzyComparePrecision_;
};

}

I want this class to contain only static members and not be instantiable. Current idea is to call Utilities::init() function in void main(), which initializes default values for members of class Double.

Is it possible to set default fuzzyComparePrecision_ without calling function init() in void main()? Or in other words, is it possible to set default value of fuzzyComparePrecision_ without instance of Double and without calling other function such as init()?

Thanks for your help!

9
  • 1
    BTW. Why do you create a class for that? Free functions would be nicer here (unless you need to unit test this, but you can't substitute singleton like this anyway). Commented Jul 25, 2019 at 10:32
  • 1
    Another BTW, main() returns int in standard C++, not void. It is possible to initialise static class members by defining them with an initialiser outside the class definition (in exactly one compilation unit) Commented Jul 25, 2019 at 10:36
  • 2
    @Brykyz It does matter. void main() is ill-formed. Commented Jul 25, 2019 at 10:39
  • 1
    Possible duplicate of How to initialize private static members in C++? Commented Jul 25, 2019 at 10:47
  • 2
    Why don't you make Double a namespace and implement all of those as functions? After all, that is what they are. Doing it with a class looks pretty much like Java style - are you coming from there? Other than that, the init function looks like code smell. The code should work even when somebody forgot about this. If you want to use constants, better have variables with the constexpr keyword, or, in your contex, use something like std::numeric_limits<double>::epsilon(). Commented Jul 25, 2019 at 10:52

2 Answers 2

2

It's not only possible, it's (almost) required to do so.

Starting from C++17, you can declare any static variable as inline, and initialize it in class body:

class Double {
private:
    inline static int fuzzyComparePrecision_ = 0;
};

Before C++17, every* static class member requires an out-of-class definition.

It can (and usually should) be combined with initialization, to avoid dealing with uninitialized variables.

You have to provide the following (in cpp file):

int Utilities::Double::fuzzyComparePrecision_;

But you can also extend it with initialization:

int Utilities::Double::fuzzyComparePrecision_ = 0;

*There are exceptions - const static members can be initialized in class body with another constant expression.

Sign up to request clarification or add additional context in comments.

2 Comments

You can make it inline now too
@LightnessRacesinOrbit Added that :)
2

To initialize static member variables you have two ways:

  1. If you are using C++17 you can do this with inline static member variables:
    class Double {
    private:
        inline static int fuzzyComparePrecision_ = 2;
    }
    
  2. For earlier version of C++ you have to do it outside the class declaration in a source file (it can't be in a header file):
    class Double {
    private:
        static int fuzzyComparePrecision_;
    }
    
    int Double::fuzzyComparePrecision_ = 2;
    

7 Comments

"To make your class not instanciable, declare it as static" Can you link us to a live demo of this working?
Just curious, is there any big difference between those ways? In other words, are there any cases which requires first or second solution?
@Brykyz There are two differences: The first method is only available in modern C++17 compilers; The first method can be used in header files and eases the creation of header-only libraries.
Other than that no. I still quite like out-of-class definitions, personally, but in practice it's hard to think of an objective reason to use them nowadays, at least in the sense that they have no notable advantages over the inline variety that I can think of
@LightnessRacesinOrbit Thanks for pointing out that static classes can be instantiated. I never tried that before and somehow assumed that obviously this must be the usage of the keyword. Was just always a bit wondering about why do members still have to be marked as static explicitly... ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.