How to implement static class members in a header-only library? [duplicate] - c++

This question already has answers here:
C++: Header-only project, static const non-integral
(1 answer)
How can you define const static std::string in header file?
(2 answers)
C++ static const string in header c++11
(2 answers)
Closed 2 years ago.
I am implementing a new header-only Library in VS2019, targeting C++11. As discussed (How to initialize a static const member in C++?) you cannot initialize a non-int static class member in-line.
class A {
private:
static const std::string SPECIAL_KEY = "A8787HHH"; //NOT OK
/*...*/
};
Instead you have to define it outside the class, typically in a CPP file:
class A {
private:
static const std::string SPECIAL_KEY;
/*...*/
};
const std::string A::SPECIAL_KEY = "A8787HHH";
But in a header-only library this runs into problems. I tried to do the above all in the same header and it worked in a simple test-app, but in real use I got linker errors that symbol A::SPECIAL_KEY was multiply defined, not surprising really as the header will get included in multiple places (How to initialize private static members in C++?)
In C++17 you can define in-line (https://stackoverflow.com/a/45062055/197229) but that's not any help to me on this code-base. C++ doesn't provide static class constructors either.
Header-only libraries have become quite widely used so is there a standard workaround to what must be a common sort of problem, until such time as we might be able to upgrade to C++17?

Related

Static variable in h-file C++ template library. Is it OK? [duplicate]

This question already has answers here:
How to have static data members in a header-only library?
(3 answers)
Closed 6 years ago.
I am developing lightweight parser as C++ h-file template library.
Gramma is described in specific BNF-like notation using overloaded operators on some classes which should be enumerated somehow. I need just one global variable as some counter performing it.
I do not want to use extern int var; in h-file and int var; in cpp-file because all my stuff in single header file and now the user just needs to include it.
I can declare static int var; in header file but copy of this variable appears in all object files where my header file is included.
Is it OK for template library?
Any suggestions?
As already mentioned you can use singleton pattern.
This version doesn't require definition of static member in template cpp file.
template <typename T> class Tmpl
{
public:
static Tmpl<T>& GlobalInstance()
{
static Tmpl<T> m_Singleton;
return m_Singleton;
};
};

Correct syntax for array of static class method pointers [duplicate]

This question already has answers here:
How to initialize private static members in C++?
(18 answers)
Closed 7 years ago.
I'm new to function pointers and am getting hung up on syntax. What I'm trying to do is define, within a class, an array of functions to do string matching. The matching functions and their storing array will be static since they will be shared by all instances of the class. The functions are stored in an array so I can iterate through within match() and try different ones. Also, I'm trying to typedef the function pointer globally because similar matching functions will be used in many such classes. I've found some stuff suggesting that the signature should maybe be bool(Money::FP)(char str) but, if true, is there no way that I can define this globally (i.e. for classes other than "Money")?
The code below does not compile so please consider it as pseudocode for what I'm trying to accomplish.
Money.h:
typedef bool(*FP)(char* str);
class Money
{
private:
static FP matchers[3] = {
Money::m1,
Money::m2,
Money::m3
};
static bool m1(char* str);
static bool m2(char* str);
static bool m3(char* str);
public:
static void match(char* str);
};
It's not working because Money::m1 refers to Money type inside its declaration. Try to decouple them, eg
class Money {
private:
static FP matchers[3];
};
FP Money::matchers[3] = {
Money::m1,
Money::m2,
Money::m3
};
In any case you might consider using std::function<bool(char*)> instead that a function pointer, since you are working with C++. Performance is not an issue until you prove it to be an issue.

What are the possible advantages of using the "static" directive outside of a class? [duplicate]

This question already has answers here:
The static keyword and its various uses in C++
(9 answers)
Closed 8 years ago.
I've been doing some experimenting with function libraries and namespaces. I noticed that you can declare a function in a namespace as static, although it is not within a class declaration:
hpp:
ANameSpace
{
static void aFunc();
};
cpp:
ANameSpace
{
static void aFunc()
{
std::cout<<"Static function called"<<std::endl;
}
};
I understand the concept of static class members and how they can be very useful, but are there any particular advantages to using static outside a class?
Note: I cast the final vote to close this question (can't delete because there is an answer) because the reference cited as dup, although it is much broader in scope, contains a detailed discussion of static. But I'm not sure if it exactly answers the question as I have rephrased it now.
A static global function is visible only in the scope of the file. This is probably due to C compatibility, where this was also possible.
This sums up every possible use of static pretty well.

setting static member variable inside a static method [duplicate]

This question already has answers here:
Undefined reference to static variable [duplicate]
(2 answers)
Closed 9 years ago.
I am beginner to C++ and have a doubt about static member variables and member functions.
I have implemented a class as follows -
class Foo
{
private:
static int myVariable;
public:
static void setMyVariable()
{
myVariable = 100;
}
static void resetMyVariable()
{
myVariable = 0;
}
};
There are following considerations when I wrote a code like that -
I want only one instance of class Foo. Thats why I made all member variables and functions as static.
I don't want the outside code to touch myVariable
I have put this class in a header file and included in my main file. When I do this, I get an error undefined reference to Foo::myVariable
I want to know if I can write a code which can satisfy above requirements?
Thanks !
You need to define static class variables somewhere:
e.g. in your main C++ file,
int Foo::myVariable;
Note that technically, by making everything static, you may have no instances of Foo.

C++ Shared Library not Allowing Static Data Member Access [duplicate]

This question already has answers here:
What does it mean to have an undefined reference to a static member?
(2 answers)
Closed 9 years ago.
I have a .cpp file that looks something like this:
//other code
namespace {
class C1;
class C2;
class C2{
public: static int counter;
//member functions here
};
class C1{
//other code
C2::counter = 10;
};
}
When I run 'make' I get the following error:
relocation R_386_GOTOFF against undefined symbol '(anonymous namespace)::C2::counter' can not be used when making a shared object...
Am I missing something simple here? Shouldn't the static int be available for class C1 to change it? Also, I am developing this as a part of the Clang library's. Also, I can share the Makefile if that helps.
You have missed out on providing the definition of you static variable. This definition must occur outside the class and only one definition is allowed. Usual way to do this is to provide the definition in the implementation file.
Because you are directly using it, without providing any definition for it, you are getting the error.