C++ – Class Containing Constants of std::string

c++constantsstaticstring

So I'm currently working on a school-project with C++, which I'm not really familiar with.
I would like to create a class, containing all my constants (string,int,double,own classes)
I was trying this, which has always worked for me in Java:

class Reference {


    //Picture-Paths
    public:
    static const std::string deepSeaPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";
    static const std::string shallowWaterPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";
    static const std::string sandPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";
    static const std::string earthPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";
    static const std::string rocksPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";
    static const std::string snowPath = "E:\\Development\\C++\\Material\\terrain\\deep_sea.tga";

};

In C++, however, I get the following error:

Error   C2864   'Reference::Reference::earthPath': a static data member with an in-class initializer must have non-volatile const integral type bio-sim-qt  e:\development\c++\bio-sim-qt\bio-sim-qt\Reference.hpp  16  1   

So is there any way for me to store for example String-Constants like this?
If yes, is there even a better way to do it? If no, is there another way (#define?) ?


Best Answer

In C++17, the recommended way of defining string constants if by using an inline constexpr std::string_view. Example:

namespace reference
{
    inline constexpr std::string_view deepSeaPath{R"(something)"};
    // ...
}

This is great because:

  • std::string_view is a lightweight non-owning wrapper that can efficiently refer to string literals without any additional costs.

  • std::string_view seamlessly interoperates with std::string.

  • Defining the variables as inline prevents ODR issues.

  • Defining the variables as constexpr makes it clear to both the compiler and other developers that these are constants known at compile-time.


If you do not have the luxury of using C++17, here's a C++11 solution: define your constants as constexpr const char* in a namespace:

namespace reference
{
    constexpr const char* deepSeaPath{R"(something)"};
    // ...
}