why can't push static const member into vector? [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
why can't push static const member into vector?
static const, static const constexpr, can't push into
static, non-static, and static const outside class, can push
sorry. I missed scope specifier , well I mean the situation that added specifier, can’t push static const member
struct A {
static const constexpr int sccv = 0;
static const int scv = 0;
static int sv = 0;
const int cv = 0;
};
int main () {
std::vector<int> vec;
vec.push_back(A::sccv); // error
vec.push_back(A::scv); // error
vec.push_back(A::sv); // pass
vec.push_back((new A())->cv); // pass
static const int sc = 0;
vec.push_back(sc); // pass
}

First I will assume that you wrote A:: at point-of-use, otherwise none of this code would have compiled.
When you "use" an object that has namespace-scope or is a class member, that is declared static, you must generally have a definition for it somewhere.
It might seem weird that a definition is needed even though you provided an initialiser at the point of declaration. That's because providing an initial value is only a small part of what a definition does. The more important part is giving the object a home, somewhere to live, specifying which compiled "module" will host the memory required for the object's existence. Like any object, your static member needs to be instantiated somewhere; the fact that it is lexically declared inside a class definition is a bit of a red herring.
So:
struct A {
static const constexpr int sccv = 0;
static const int scv = 0;
static int sv = 0;
const int cv = 0;
};
// In precisely one source file:
const constexpr int A::sccv;
const int A::scv;
int A::sv;
Now you won't get that "undefined reference" linker error any more.
There are some exceptions to the rule, and there are some scenarios in which compiler optimisations result in your program appearing to work regardless.

Related

Why can a const function not be called on a const object in this case? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
Hey I'm trying to look at the basics of OOP and I do not understand why in this particular instance, I cannot call a member function which is defined const on an object which is also const. But since both are deemed const, I dont change behavior for any of the objects or their attributes right? What does this mean? VS code says that the object has type qualifiers that are incompatible with the member function g. Any information will be appreciated. Thank you!
class D
{
private:
double x;
public:
D()
{
x = 2.0;
}
const double &g() {
return x;
}
};
int main()
{
const D d;
d.g();
}
You placed the const in the wrong place. D::g is not a const-member function. It is a non-const member function (that returns a const reference). You want:
const double& g() const {
//^^ const member function
//^---------^ return type
return x;
}

What are the differences (object size, performance, etc.) between a function that returns a local static and a function that returns a static member? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
My derived class needs to provide a function that returns a std::vector& to the caller.
I could declare a static member and initialize it either in the constructor or in the 'global scope' of the CPP file. I could also declare a local static in the derived function and return it.
The first option has declaration, initialization and return functionality in three separate locations of the code, while the second option consolidates all three elements in the same place. What are the object size, performance, etc. differences between these approaches?
Edits start here after reading comments through SergeyA. I am editing the code example of PeterT, adding a sample to show that the constructor utilizes push_back. So I must admit to SergeyA that initialization does occur in the global scope and as written below, there are four separate locations where the variable s_val appears.
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
ex();
static intVec s_val;
intVec& getVal();
};
//ex.cpp
intVec ex::s_val = intVec(5);
ex::ex()
{
if (s_val.size() == 0) {
s_val.reserve(5);
s_val.push_back(1);
s_val.push_back(4);
s_val.push_back(0);
s_val.push_back(2);
s_val.push_back(3);
}
assert(s_val.size() == 5);
}
intVec& ex::getVal()
{
return s_val;
}
I want to modernize and simplify the code to use an initializer list. It sounds like returning a global static allows me to do that in a clean and efficient manner. Is this correct ?
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
intVec& getVal();
};
//ex.cpp
static intVec s_val = { 1, 4, 0, 2, 3 };
intVec& ex::getVal()
{
assert(s_val.size() == 5);
return s_val;
}
A local static will incur the cost of an initialization guard (a mutex lock) on every call to the function. This is due to C++11 guaranteeing thread-safe initialization of statics, which for local statics means access serialization.
A global static (which also includes static class members) does not incur that cost, since global static are initialized before main() runs.
You can see the initialization guards in the generated assembly:
https://godbolt.org/z/BzdzvN
When you do do this
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
static intVec s_val;
intVec& getVal();
};
//ex.cpp
intVec ex::s_val = intVec(5);
intVec& ex::getVal()
{
return s_val;
}
Then the initialization code for instantiating the vector happens before main()
But if you do
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
intVec& getVal();
};
//ex.cpp
intVec& ex::getVal()
{
static intVec s_val = intVec(5);
return s_val;
}
Then the initialization of the static variable (the constructor of std::vector being called) happens when you call the function for the first time.
This can be an issue in multi-threaded contexts where it can lead to race-conditions, but in this case you're returning a mutable reference to a static std::vector so I'm assuming that threading doesn't matter for this specific case anyway. (nvm. see Nikos answer to this question for why that's not longer a concern)
There is some misunderstanding there. If you declare a static member of the class, you can't initialize it in the constructor. You can obviously assign it in the constructor, but it will be assigned whenever a new object will be created (potentially multiple times) which probably doesn't make any sense for most applications.
If you declare a static member, you should either make it a constexpr and initialize in-place, or initialize outside of class definition. The latter exposes you to all the glory of static initialization order fiasco, unless you can guarantee a compile-time initialization for your member.
Function-local static has not issues with initialization order, and have a defined order. However, with function local static you'd pay a minuscule price of a branch (predicted) every time you call the function. For most applications, this is not even worth talking about.

when/why should i use static in c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I found Why/when should I declare a variable using static?, but the tags is about objective-c .
I can't make sure is there any difference in usage details between c++ and objective-c when you use static, so when/why should I use static in c++?
static has a couple of independent meanings, depending on context.
void f() { ... }
static void g() { ... }
Here, f has "external linkage", which means that its name is visible in other translation units. That is, in another source file you could have void f(); and then you could call the function f.
g, on the other hand, because it's marked static, has "internal linkage". You can call it from code in the same source file, but you cannot call it from another source file.
Same for objects:
int i = 3; // external linkage
static int j = 4; // internal linkage
And a small complication: you can define a static object inside a function.
void f() {
static int i = 3;
std::cout << i << '\n';
++i;
}
Here, i has no linkage. It's only visible inside the function. It gets initialized the first time the function is called (and doesn't get initialized at all if the function isn't called). So the first time that f is called it will write "3" to the console. On the second call it will write "4", etc. Understanding the behavior of objects with destructors is left as an exercise for the reader.
Inside a class definition it's completely different.
class C {
public:
void f();
static void g();
int i;
static int j;
};
Here, when you call f you must call it on an object of type C, and f can use data members of that object, that is, it can look at and change both i and j. When you call g there is no associated object. It's still a member of C, so it can look at and change j, because j, too, is not associated with any object. There's only one j, and it's shared by all objects of type C.

static member vs static const member instantiation - what's the difference? [duplicate]

This question already has answers here:
Why can't I initialize non-const static member or static array in class?
(5 answers)
Closed 7 years ago.
What exactly is the difference between these two members in question of initialization and instantiation?:
class Test {
// ctor, dtor, ... here
private:
static int m_test = 0; // error - non-const ...
static const int m_const_test = 0; // working - const ...
};
Why is initialization of non-const members not valid?
And when will both variables (assuming non-const member without init!) be instantiated?
Edit: Even if a good part of this question is superimposable to the mentioned posts, i don't think that every part of my question is answered in these entries.
BR, Tuna
If multiple compilation units include your class definition then in which one should be your static int m_test = 0 be placed? For const static ... it does not matter because it is const.
m_const_test being declared as const can´t be changed.
So, you can save a little bit of time using m_const_test, but is not as flexible as m_test.

Forward declaration error in C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have a class defined in a hpp file which I'm trying to use in another header, so I made a forward declaration to it (I only want to use it by reference as a function parameter). For some reason I keep getting a compile error because of it. I can't figure out why it's not working. Here are my codes:
//something.hpp:
class MyClass;
void someFunction (MyClass& mc);
...
//something.cpp:
#include "MyClass.hpp"
void someFunction (MyClass& mc) {...}
...
//MyClass.hpp:
class MyClass {
const char* myText;
public:
MyClass (const char* text) : myText(text) {}
};
//main.cpp:
int main () {
...
someFunction (MyClass ("some text here"));
...
}
And I get an error from main() which says:
'<function-style-cast>' : cannot convert from 'const char [15]' to 'MyClass'
Source or target has incomplete type
If I understand it right, it means that the compiler doesn't find the definition of MyClass, only the predeclaration of it (even though I included MyClass.hpp in something.cpp), that's why it says it's incomplete. What did I miss here?
The function
void someFunction (MyClass& mc);
is accepting a non-const reference to a MyClass instance.
You are not allowed to pass a temporary to such a function.
The code should be
#include "MyClass.hpp"
...
int main() {
MyClass m("some text here");
someFunction(m);
}
or alternatively you need to accept a const reference.
void someFunction (const MyClass& mc);
I don't think that the problem is related to the forward declaration, but rather that you cannot pass a temporary to a function taking a reference as argument. In fact, if you put all your definitions in a single file, it still doesn't compile. On the other hand, if you replace the code of the main with the following, it will compile:
int main() {
MyClass mc("Some text here");
someFunction(mc);
}