146

I have a class

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

Where is the best place to initialize the string s in the source file?

JFMR
  • 23,265
  • 4
  • 52
  • 76
Thomas
  • 2,939
  • 6
  • 32
  • 29

5 Answers5

199

Anywhere in one compilation unit (usually a .cpp file) would do:

foo.h

class foo {
    static const string s; // Can never be initialized here.
    static const char* cs; // Same with C strings.

    static const int i = 3; // Integral types can be initialized here (*)...
    static const int j; //     ... OR in cpp.
};

foo.cpp

#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;

(*) According to the standards you must define i outside of the class definition (like j is) if it is used in code other than just integral constant expressions. See David's comment below for details.

squelart
  • 11,261
  • 3
  • 39
  • 43
  • 31
    I have upvoted, but after reviewing the standard there is an error in your code: `i` must be *defined* in the cpp. §9.4.2/4 *If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.* – David Rodríguez - dribeas Apr 09 '10 at 08:35
  • 3
    Based on your quote from the standards, it seems `i` would have to be be defined *only* if it was used somewhere else than in integral constant expressions, right? In this case you cannot say that there is an error because there is not enough context to be sure -- or stricly speaking the above example is correct if there is no other code. Now I do appreciate your comment (+1), I'm still learning things myself! So I'll try and clarify that point in the answer, please let me know if it's better... – squelart Apr 09 '10 at 12:12
  • 1
    @squelart Sorry if I sound dumb but an example of statement other than integral constant expression would be? – Saksham Jul 20 '13 at 16:20
  • 3
    @Saksham For example calling a function, e.g.: `int f() { return 42; } class foo { static const int i = f(); /* Error! */ }` Note that C++11 allows calling 'constexpr' functions: `constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }` – squelart Jul 21 '13 at 07:49
  • 2
    @squelart I read the text such that the definition must be supplied if the member is used at all - the wording in the standard doesn't limit that requirement to integral constant expressions. – VladLosev Nov 01 '13 at 17:30
  • btw, we can cope `const static bool` member data with the same of `const static int` – BugKiller Sep 03 '19 at 13:24
24

Since C++17 the inline specifier also applies to variables. You can now define static member variables in the class definition:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};
plexando
  • 1,151
  • 6
  • 22
13

In a translation unit within the same namespace, usually at the top:

// foo.h
struct foo
{
    static const std::string s;
};

// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives

// bar.h
namespace baz
{
    struct bar
    {
        static const float f;
    };
}

// bar.cpp
namespace baz
{
    const float bar::f = 3.1415926535;
}
GManNickG
  • 494,350
  • 52
  • 494
  • 543
13

Static members need to be initialized in a .cpp translation unit at file scope or in the appropriate namespace:

const string foo::s( "my foo");
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
1

Only integral values (e.g., static const int ARRAYSIZE) are initialized in header file because they are usually used in class header to define something such as the size of an array. Non-integral values are initialized in implementation file.