Is there any technique or compiler extension keyword to declare class member variables inside class member functions? Something like
struct test_t{
void operator ()(){
instance_local int i = 0;
}
};
The best that came in my mind was using thread_local and then executing the member function inside another thread, but this would be too ugly to be useful.
EDIT: example
Well I'm really sorry for the following probably confusing example (it is related to my question yesterday Is there any problem in jumping into if(false) block?). I really tried to make a less confusing up...
#include <iostream>
#define instance_local thread_local
struct A{
A(int i) :
i(i)
{
}
void dosomethinguseful(){
std::cout << i << std::endl;
}
int i;
};
struct task1{
int part;
task1() : part(0){}
void operator ()(){
int result_of_calculation;
switch (part) {
case 0:{
//DO SOME CALCULATION
result_of_calculation = 5;
instance_local A a(result_of_calculation);
if(false)
case 1:{ a.dosomethinguseful();}
part++;
}
default:
break;
}
}
};
int main(){
task1 t;
t();
t();
return 0;
}
instance_local A a(result_of_calculation); that is what i could get from such a keyword instead of making a smart pointer for a.
You're describing a coroutine. Here a rough draft of what it could look like (I'm not an expert in coroutine)
auto task1() -> some_awaitable_type {
result_of_calculation = 5;
A a(result_of_calculation);
co_yield;
a.dosomethinguseful();
}
This could be called like this:
some_awaitable_type maybe_do_something = task1();
// calculation done here
// dosomethinguseful called here
co_await maybe_do_something();
There is not. The compiler needs to know the structure of the class without compiling all the method implementations. If you could slip instance_local int foo into a method body, that would make the size of the data structure 4 bytes larger.
On a more principled level, it's not good to hide data. The equivalent feature for global variables that you might be thinking of, static local variables, is a carryover from C that is widely considered to be an anti-pattern:
Why are static variables considered evil?
Not directly, no.
You could define a:
static std::map<test_t*, int> is;
…where the first part of each element is a this pointer.
But, why?
Make a member variable.
Related
I am trying to optimize the run time of my code and I was told that removing unnecessary virtual functions was the way to go. With that in mind I would still like to use inheritance to avoid unnecessary code bloat. I thought that if I simply redefined the functions I wanted and initialized different variable values I could get by with just downcasting to my derived class whenever I needed derived class specific behavior.
So I need a variable that identifies the type of class that I am dealing with so I can use a switch statement to downcast properly. I am using the following code to test this approach:
Classes.h
#pragma once
class A {
public:
int type;
static const int GetType() { return 0; }
A() : type(0) {}
};
class B : public A {
public:
int type;
static const int GetType() { return 1; }
B() : {type = 1}
};
Main.cpp
#include "Classes.h"
#include <iostream>
using std::cout;
using std::endl;
using std::getchar;
int main() {
A *a = new B();
cout << a->GetType() << endl;
cout << a->type;
getchar();
return 0;
}
I get the output expected: 0 1
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
There's the typeid() already enabled with RTTI, there's no need you implement that yourself in an error prone and unreliable way.
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Certainly no! That's a heavy indicator of bad (sic!) class inheritance hierarchy design.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
The typical way to realize polymorphism without usage of virtual functions is the CRTP (aka Static Polymorphism).
That's a widely used technique to avoid the overhead of virtual function tables when you don't really need them, and just want to adapt your specific needs (e.g. with small targets, where low memory overhead is crucial).
Given your example1, that would be something like this:
template<class Derived>
class A {
protected:
int InternalGetType() { return 0; }
public:
int GetType() { static_cast<Derived*>(this)->InternalGetType(); }
};
class B : public A<B> {
friend class A<B>;
protected:
int InternalGetType() { return 1; }
};
All binding will be done at compile time, and there's zero runtime overhead.
Also binding is safely guaranteed using the static_cast, that will throw compiler errors, if B doesn't actually inherits A<B>.
Note (almost disclaimer):
Don't use that pattern as a golden hammer! It has it's drawbacks also:
It's harder to provide abstract interfaces, and without prior type trait checks or concepts, you'll confuse your clients with hard to read compiler error messages at template instantiantion.
That's not applicable for plugin like architecture models, where you really want to have late binding, and modules loaded at runtime.
If you don't have really heavy restrictions regarding executable's code size and performance, it's not worth doing the extra work necessary. For most systems you can simply neglect the dispatch overhead done with virtual function defintions.
1)The semantics of GetType() isn't necessarily the best one, but well ...
Go ahead and use virtual functions, but make sure each of those functions is doing enough work that the overhead of an indirect call is insignificant. That shouldn't be very hard to do, a virtual call is pretty fast - it wouldn't be part of C++ if it wasn't.
Doing your own pointer casting is likely to be even slower, unless you can use that pointer a significant number of times.
To make this a little more concrete, here's some code:
class A {
public:
int type;
int buffer[1000000];
A() : type(0) {}
virtual void VirtualIncrease(int n) { buffer[n] += 1; }
void NonVirtualIncrease(int n) { buffer[n] += 1; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 1; }
};
class B : public A {
public:
B() : {type = 1}
virtual void VirtualIncrease(int n) { buffer[n] += 2; }
void NonVirtualIncrease(int n) { buffer[n] += 2; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 2; }
};
int main() {
A *a = new B();
// easy way with virtual
for (int i = 0; i < 1000000; ++i)
a->VirtualIncrease(i);
// hard way with switch
for (int i = 0; i < 1000000; ++i) {
switch(a->type) {
case 0:
a->NonVirtualIncrease(i);
break;
case 1:
static_cast<B*>(a)->NonVirtualIncrease(i);
break;
}
}
// fast way
a->IncreaseAll();
getchar();
return 0;
}
The code that switches using a type code is not only much harder to read, it's probably slower as well. Doing more work inside a virtual function ends up being both cleanest and fastest.
(I know) In c++ I can declare variable out of scope and I can't run any code/statement, except for initializing global/static variables.
IDEA
Is it a good idea to use below tricky code in order to (for example) do some std::map manipulation ?
Here I use void *fakeVar and initialize it through Fake::initializer() and do whatever I want in it !
std::map<std::string, int> myMap;
class Fake
{
public:
static void* initializer()
{
myMap["test"]=222;
// Do whatever with your global Variables
return NULL;
}
};
// myMap["Error"] = 111; => Error
// Fake::initializer(); => Error
void *fakeVar = Fake::initializer(); //=> OK
void main()
{
std::cout<<"Map size: " << myMap.size() << std::endl; // Show myMap has initialized correctly :)
}
One way of solving it is to have a class with a constructor that does things, then declare a dummy variable of that class. Like
struct Initializer
{
Initializer()
{
// Do pre-main initialization here
}
};
Initializer initializer;
You can of course have multiple such classes doing miscellaneous initialization. The order in each translation unit is specified to be top-down, but the order between translation units is not specified.
You don't need a fake class... you can initialize using a lambda
auto myMap = []{
std::map<int, string> m;
m["test"] = 222;
return m;
}();
Or, if it's just plain data, initialize the map:
std::map<std::string, int> myMap { { "test", 222 } };
Is it a good idea to use below tricky code in order to (for example)
do some std::map manipulation ?
No.
Any solution entailing mutable non-local variables is a terrible idea.
Is it a good idea...?
Not really. What if someone decides that in their "tricky initialisation" they want to use your map, but on some system or other, or for not obvious reason after a particular relink, your map ends up being initialised after their attempted use? If you instead have them call a static function that returns a reference to the map, then it can initialise it on first call. Make the map a static local variable inside that function and you stop any accidental use without this protection.
§ 8.5.2 states
Except for objects declared with the constexpr specifier, for which
see 7.1.5, an initializer in the definition of a variable can consist
of arbitrary expressions involving literals and previously declared
variables and functions, regardless of the variable’s storage duration
therefore what you're doing is perfectly allowed by the C++ standard. That said, if you need to perform "initialization operations" it might be better to just use a class constructor (e.g. a wrapper).
What you've done is perfectly legal C++. So, if it works for you and is maintainable and understandable by anybody else who works with the code, it's fine. Joachim Pileborg's sample is clearer to me though.
One problem with initializing global variables like this can occur if they use each other during initialization. In that case it can be tricky to ensure that variables are initialized in the correct order. For that reason, I prefer to create InitializeX, InitializeY, etc functions, and explicitly call them in the correct order from the Main function.
Wrong ordering can also cause problems during program exit where globals still try to use each other when some of them may have been destroyed. Again, some explicit destruction calls in the correct order before Main returns can make it clearer.
So, go for it if it works for you, but be aware of the pitfalls. The same advice applies to pretty much every feature in C++!
You said in your question that you yourself think the code is 'tricky'. There is no need to overcomplicate things for the sake of it. So, if you have an alternative that appears less 'tricky' to you... that might be better.
When I hear "tricky code", I immediately think of code smells and maintenance nightmares. To answer your question, no, it isn't a good idea. While it is valid C++ code, it is bad practice. There are other, much more explicit and meaningful alternatives to this problem. To elaborate, the fact that your initializer() method returns void* NULL is meaningless as far as the intention of your program goes (i.e. each line of your code should have meaningful purpose), and you now have yet another unnecessary global variable fakeVar, which needlessly points to NULL.
Let's consider some less "tricky" alternatives:
If it's extremely important that you only ever have one global instance of myMap, perhaps using the Singleton Pattern would be more fitting, and you would be able to lazily initialize the contents of myMap when they are needed. Keep in mind that the Singleton Pattern has issues of its own.
Have a static method create and return the map or use a global namespace. For example, something along the lines of this:
// global.h
namespace Global
{
extern std::map<std::string, int> myMap;
};
// global.cpp
namespace Global
{
std::map<std::string, int> initMap()
{
std::map<std::string, int> map;
map["test"] = 222;
return map;
}
std::map<std::string, int> myMap = initMap();
};
// main.cpp
#include "global.h"
int main()
{
std::cout << Global::myMap.size() << std::endl;
return 0;
}
If this is a map with specialized functionality, create your own class (best option)! While this isn't a complete example, you get the idea:
class MyMap
{
private:
std::map<std::string, int> map;
public:
MyMap()
{
map["test"] = 222;
}
void put(std::string key, int value)
{
map[key] = value;
}
unsigned int size() const
{
return map.size();
}
// Overload operator[] and create any other methods you need
// ...
};
MyMap myMap;
int main()
{
std::cout << myMap.size() << std::endl;
return 0;
}
In C++, you cannot have statements outside any function. However, you have global objects declared, and constructor (initializer) call for these global objects are automatic before main starts. In your example, fakeVar is a global pointer that gets initialized through a function of class static scope, this is absolutely fine.
Even a global object would do provide that global object constructor does the desired initializaton.
For example,
class Fake
{
public:
Fake() {
myMap["test"]=222;
// Do whatever with your global Variables
}
};
Fake fake;
This is a case where unity builds (single translation unit builds) can be very powerful. The __COUNTER__ macro is a de facto standard among C and C++ compilers, and with it you can write arbitrary imperative code at global scope:
// At the beginning of the file...
template <uint64_t N> void global_function() { global_function<N - 1>(); } // This default-case skips "gaps" in the specializations, in case __COUNTER__ is used for some other purpose.
template <> void global_function<__COUNTER__>() {} // This is the base case.
void run_global_functions();
#define global_n(N, ...) \
template <> void global_function<N>() { \
global_function<N - 1>(); /* Recurse and call the previous specialization */ \
__VA_ARGS__; /* Run the user code. */ \
}
#define global(...) global_n(__COUNTER__, __VA_ARGS__)
// ...
std::map<std::string, int> myMap;
global({
myMap["test"]=222;
// Do whatever with your global variables
})
global(myMap["Error"] = 111);
int main() {
run_global_functions();
std::cout << "Map size: " << myMap.size() << std::endl; // Show myMap has initialized correctly :)
}
global(std::cout << "This will be the last global code run before main!");
// ...At the end of the file
void run_global_functions() {
global_function<__COUNTER__ - 1>();
}
This is especially powerful once you realize that you can use it to initialize static variables without a dependency on the C runtime. This means you can generate very small executables without having to eschew non-zero global variables:
// At the beginning of the file...
extern bool has_static_init;
#define default_construct(x) x{}; global(if (!has_static_init()) new (&x) decltype(x){})
// Or if you don't want placement new:
// #define default_construct(x) x{}; global(if (!has_static_init()) x = decltype(x){})
class Complicated {
int x = 42;
Complicated() { std::cout << "Constructor!"; }
}
Complicated default_construct(my_complicated_instance); // Will be zero-initialized if the CRT is not linked into the program.
int main() {
run_global_functions();
}
// ...At the end of the file
static bool get_static_init() {
volatile bool result = true; // This function can't be inlined, so the CRT *must* run it.
return result;
}
has_static_init = get_static_init(); // Will stay zero without CRT
This answer is similar to Some programmer dude's answer, but may be considered a bit cleaner. As of C++17 (that's when std::invoke() was added), you could do something like this:
#include <functional>
auto initializer = std::invoke([]() {
// Do initialization here...
// The following return statement is arbitrary. Without something like it,
// the auto will resolve to void, which will not compile:
return true;
});
This has defeated me. I want to have a static class variable which is a pointer to a (non-static) member function. I've tried all sorts of ways, but with no luck (including using typedefs, which just seemed to give me a different set of errors). In the code below I have the static class function pointer funcptr, and I can call it successfully from outside the class, but not from within the member function CallFuncptr - which is what I want to do. Any suggestions?
#include <stdio.h>
class A
{
public:
static int (A::*funcptr)();
int Four() { return 4;};
int CallFuncptr() { return (this->*funcptr)(); }
// doesn't link - undefined reference to `A::funcptr'
};
int (A::*funcptr)() = &A::Four;
int main()
{
A fred;
printf("four? %d\n", (fred.*funcptr)()); // This works
printf("four? %d\n", fred.CallFuncptr()); // But this is the way I want to call it
}
Try this instead:
#include <iostream>
class A {
public:
typedef int (A::*AMemFn)();
static AMemFn funcptr;
int Four() { return 4; }
int CallFuncptr() { return (this->*funcptr)(); }
};
A::AMemFn A::funcptr = &A::Four;
int main()
{
A fred;
std::cout << "four? " << fred.CallFuncptr() << std::endl;
}
jweyrich has a nice looking work around (and I suggest you use it), but I thought I'd elaborate on what the real problem in the code is:
Your problem is this line:
int (A::*funcptr)() = &A::Four;
This is defining a global variable called funcptr that is of the right type, rather than A::funcptr.
What you need is this mess:
int (A::*(A::funcptr))() = &A::Four;
This ugly mess is why I suggest you go down the typedef path to get a nice looking version like jweyrich's solution.
A static variable is not a member of a particular object -- it can only be accessed through the classes namespace. CallFuncptr should be rewritten:
int CallFuncptr() { return (*funcptr)();
which I think should work, since this function can access functions in A's namespace without specifying it.
Also, function pointers are more of a C construct than C++. You can access the static variable outside the class with the code:
A::CallFuncptr
since CallFunctptr just resides in A's namespace
I'm considering a certain solution where I would like to initialize a cell of an array that is defined in other module (there will be many modules initializing one table). The array won't be read before running main (so there is not problem with static initialization order).
My approach:
/* secondary module */
extern int i[10]; // the array
const struct Initialize {
Initialize() { i[0] = 12345; }
} init;
/* main module */
#include <stdio.h>
int i[10];
int main()
{
printf("%d\n", i[0]); // check if the value is initialized
}
Compiler won't strip out init constant because constructor has side effects. Am I right? Is the mechanism OK? On GCC (-O3) everything is fine.
//EDIT
In a real world there will be many modules. I want to avoid an extra module, a central place that will gathered all minor initialization routines (for better scalability). So this is important that each module triggers its own initialization.
This works with MSVC compilers but with GNU C++ does not (at least for me). GNU linker will strip all the symbol not used outside your compilation unit. I know only one way to guarantee such initialization - "init once" idiom. For examle:
init_once.h:
template <typename T>
class InitOnce
{
T *instance;
static unsigned refs;
public:
InitOnce() {
if (!refs++) {
instance = new T();
}
}
~InitOnce() {
if (!--refs) {
delete instance;
}
}
};
template <typename T> unsigned InitOnce<T>::refs(0);
unit.h:
#include "init_once.h"
class Init : public InitOnce<Init>
{
public:
Init();
~Init();
};
static Init module_init_;
secondary.cpp:
#include "unit.h"
extern int i[10]; // the array
Init::Init()
{
i[0] = 12345;
}
...
I don't think you want the extern int i[10]; in your main module, though, adf88.
EDIT
/*secondary module (secondary.cpp) */
int i[10];
void func()
{
i[0]=1;
}
.
/*main module (main.cpp)*/
#include<iostream>
extern int i[];
void func();
int main()
{
func();
std::cout<<i[0]; //prints 1
}
Compile, link and create and executable using g++ secondary.cpp main.cpp -o myfile
In general constructors are used(and should be used) for initializing members of a class only.
This might work, but it's dangerous. Globals/statics construction order within a single module is undefined, and so is module loading order (unless you're managing it explicitly). For example, you assume that during secondary.c Initialize() ctor run, i is already present. You'd have to be very careful not to have two modules initialize the same common data, or have two modules carry out initializations with overlapping side effects.
I think a cleaner design to tackle such a need is to have the owner of the common data (your main module) expose it as a global singleton, with an interface to carry out whichever data initializations needed. You'd have a central place to control init-order, and maybe even control concurrent access (using critical sections or other concurrency primitives). Along the lines of your simplified example, that might be -
/main module (main.c)/
#include
class CommonDat
{
int i;
public:
const int GetI() { return i;}
void SetI(int newI) { i = newI; }
void incI()
{
AcquireSomeLock();
i++;
ReleaseTheLock();
}
}
CommonDat g_CommonDat;
CommonDat* getCommonDat() { return &g_CommonDat; }
int main(void)
{
printf("%d",getCommonDat()->GetI());
}
It's also preferable to have the secondary modules call these interfaces at controlled times in runtime (and not during the global c'tors pass).
(NOTE: you named the files as C files, but tagged the question as c++. The suggested code is c++, of course).
May I ask why you use an array (running the risk of getting out of bounds) when you could use a std::vector ?
std::vector<int>& globalArray()
{
static std::vector<int> V;
return V;
}
bool const push_back(std::vector<int>& vec, int v)
{
vec.push_back(v);
return true; // dummy return for static init
}
This array is lazily initialized on the first call to the function.
You can use it like such:
// module1.cpp
static bool const dummy = push_back(globalArray(), 1);
// module2.cpp
static bool const dummy = push_back(globalArray(), 2);
It seems much easier and less error-prone. It's not multithread compliant until C++0x though.
Could someone please tell me if this is possible in C or C++?
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
int fun_b(){
...
}
...
}
or something similar, as e.g. a class inside a function?
thanks for your replies,
Wow, I'm surprised nobody has said yes! Free functions cannot be nested, but functors and classes in general can.
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
struct { int operator()() {
...
} } fun_b;
int q = fun_b();
...
}
You can give the functor a constructor and pass references to local variables to connect it to the local scope. Otherwise, it can access other local types and static variables. Local classes can't be arguments to templates, though.
C++ does not support nested functions, however you can use something like boost::lambda.
C — Yes for gcc as an extension.
C++ — No.
you can't create a function inside another function in C++.
You can however create a local class functor:
int foo()
{
class bar
{
public:
int operator()()
{
return 42;
}
};
bar b;
return b();
}
in C++0x you can create a lambda expression:
int foo()
{
auto bar = []()->int{return 42;};
return bar();
}
No but in C++0x you can http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions which may take another few years to fully support. The standard is not complete at the time of this writing.
-edit-
Yes
If you can use MSVC 2010. I ran the code below with success
void test()
{
[]() { cout << "Hello function\n"; }();
auto fn = [](int x) -> int { cout << "Hello function (" << x << " :))\n"; return x+1; };
auto v = fn(2);
fn(v);
}
output
Hello function
Hello function (2 :))
Hello function (3 :))
(I wrote >> c:\dev\loc\uniqueName.txt in the project working arguments section and copy pasted this result)
The term you're looking for is nested function. Neither standard C nor C++ allow nested functions, but GNU C allows it as an extension. Here is a good wikipedia article on the subject.
Clang/Apple are working on 'blocks', anonymous functions in C! :-D
^ ( void ) { printf("hello world\n"); }
info here and spec here, and ars technica has a bit on it
No, and there's at least one reason why it would complicate matters to allow it. Nested functions are typically expected to have access to the enclosing scope. This makes it so the "stack" can no longer be represented with a stack data structure. Instead a full tree is needed.
Consider the following code that does actually compile in gcc as KennyTM suggests.
#include <stdio.h>
typedef double (*retdouble)();
retdouble wrapper(double a) {
double square() { return a * a; }
return square;
}
int use_stack_frame(double b) {
return (int)b;
}
int main(int argc, char** argv) {
retdouble square = wrapper(3);
printf("expect 9 actual %f\n", square());
printf("expect 3 actual %d\n", use_stack_frame(3));
printf("expect 16 actual %f\n", wrapper(4)());
printf("expect 9 actual %f\n", square());
return 0;
}
I've placed what most people would expect to be printed, but in fact, this gets printed:
expect 9 actual 9.000000
expect 3 actual 3
expect 16 actual 16.000000
expect 9 actual 16.000000
Notice that the last line calls the "square" function, but the "a" value it accesses was modified during the wrapper(4) call. This is because a separate "stack" frame is not created for every invocation of "wrapper".
Note that these kinds of nested functions are actually quite common in other languages that support them like lisp and python (and even recent versions of Matlab). They lead to some very powerful functional programming capabilities, but they preclude the use of a stack for holding local scope frames.
void foo()
{
class local_to_foo
{
public: static void another_foo()
{ printf("whatevs"); }
};
local_to_foo::another_foo();
}
Or lambda's in C++0x.
You can nest a local class within a function, in which case the class will only be accessible to that function. You could then write your nested function as a member of the local class:
#include <iostream>
int f()
{
class G
{
public:
int operator()()
{
return 1;
}
} g;
return g();
}
int main()
{
std::cout << f() << std::endl;
}
Keep in mind, though, that you can't pass a function defined in a local class to an STL algorithm, such as sort().
int f()
{
class G
{
public:
bool operator()(int i, int j)
{
return false;
}
} g;
std::vector<int> v;
std::sort(v.begin(), v.end(), g); // Fails to compile
}
The error that you would get from gcc is "test.cpp:18: error: no matching function for call to `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, f()::G&)'
"
It is not possible to declare a function within a function. You may, however, declare a function within a namespace or within a class in C++.
Not in standard C, but gcc and clang support them as an extension. See the gcc online manual.
Though C and C++ both prohibit nested functions, a few compilers support them anyway (e.g., if memory serves, gcc can, at least with the right flags). A nested functor is a lot more portable though.
No nested functions in C/C++, unfortunately.
As other answers have mentioned, standard C and C++ do not permit you to define nested functions. (Some compilers might allow it as an extension, but I can't say I've seen it used).
You can declare another function inside a function so that it can be called, but the definition of that function must exist outside the current function:
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char* argv[])
{
int foo(int x);
/*
int bar(int x) { // this can't be done
return x;
}
*/
int a = 3;
printf( "%d\n", foo(a));
return 0;
}
int foo( int x)
{
return x+1;
}
A function declaration without an explicit 'linkage specifier' has an extern linkage. So while the declaration of the name foo in function main() is scoped to main(), it will link to the foo() function that is defined later in the file (or in a another file if that's where foo() is defined).