41

I am trying to create a static string in my class: (in my header file)

static string description = "foo";

but I'm getting this error:

IntelliSense: a member with an in-class initializer must be const

if I change it to this:

static const string description = "foo";

I get this error instead:

IntelliSense: a member of type "const std::string" cannot have an in-class initializer

What did I do wrong?

Chin
  • 19,717
  • 37
  • 107
  • 164

4 Answers4

38

What you can do is declare the string in the header and initialize it in your .cpp.

in MyClass.h

#include <string>
class MyClass
{
  static std::string foo;
}

in MyClass.cpp

#include "MyClass.h"
std::string MyClass::foo = "bar"
Kevin MOLCARD
  • 2,168
  • 3
  • 22
  • 35
13

Ignoring the specific error message the core issue is that you are trying to initialize a static member attribute in the declaration while in general that should be done in the definition.

// header
struct test {
  static std::string x;
};
// single cpp
std::string test::x = "foo";

Now back to the error messages. There is an exception in the C++03 standard that allows to provide an initializer to the declaration of a constant integral type, so that the value can be visible in all translation units that include the header and can thus be used as a constant expression:

// header
struct test {
   static const int size = 10;
};
// some translation unit can do
struct A {
   int array[test::size];
};

If the value was defined in the definition of the variable, then the compiler could only use it in that single translation unit. It seems that your compiler is doing two tests, one for const-ness and a separate one for the integral part and thus two error messages.

Another thing that might affected that design in the compiler is that the C++11 standard allows for initializers in the declaration of non-static members of a class, which will then be used in the initializer list of each constructor that does not provide a value for that field:

struct test {
   int a = 10;
   int b = 5;
   test() : a(5) // b(5) implicitly generated
   {} 
};

This is unrelated to your particular issue, as your member is static but it probably explains why the tests in the compiler were split as they are.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • What is you have header-only library? – Shital Shah May 11 '17 at 00:45
  • 1
    @ShitalShah: If you have a C++17 compiler (gcc just came out) you could use an inline variable, but the simple answer that works with all versions is that you push the variable to be a local-static variable: `struct T { static const std::string& x() { static std::string x = "foo"; return x; } };` – David Rodríguez - dribeas May 11 '17 at 09:32
4

Seperate the declaration from the definition. In the header file, do this:

static string description;

And then in exactly one translation unit (one CPP file), do this:

string type::description = "foo";
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

I don't know what exactly you need between a static member and a constant member. A static member will be associated with the class itself and not with the instances, and a constant member is a associated with the instance and will be constant.

However, this is a possible duplicate of this

Regards

Community
  • 1
  • 1