C++ create a function similar to while, if, or for - c++

Think about this code in C/C++:
bool cond = true;
while(cond){
std::cout << "cond is currently true!";
}
Is it possible to create a function that can be called like this?
myFunction(some_parameters_here){
//Code to execute, maybe use it for callbacks
myOtherFunction();
anotherFunction();
}
I know you can use function pointers and lambda functions, but I was wondering if you can. I'm pretty sure there is a way to do so, because how would while() exist?

while(condition) { expression } is not a function but a control structure / a separate language construct; it executes expression again and again as long as condition evaluates to true (i.e. something != 0).
an function definition of the form void myFunction(int someParameter) { expression }, in contrast, is executed only when it is called by another function.
Hope it helps a bit;

Caution: this solution comes without the guarantee that your code reviewer will like it.
We can use a trick similar to the one Alexandrescu uses for his SCOPE_EXIT macro (awesome one-hour conference, this bit is at 18:00).
The gist of it: a clever macro and a dismembered lambda.
namespace myFunction_detail {
struct Header {
// Data from the construct's header
};
template <class F>
void operator * (Header &&header, F &&body) {
// Do something with the header and the body
}
}
#define myPrefix_myFunction(a, b, c) \
myFunction_detail::Header{a, b, c} * [&]
Using it as follows:
myPrefix_myFunction(foo, bar, baz) {
}; // Yes, we need the semicolon because the whole thing is a single statement :/
... reconstitutes a complete lambda after macro expansion, and lands into myFunction_detail::operator* with acess to foo, bar, baz, and the body of the construct.

Related

Defining const "variable" inside if block

I have the following code:
Foo a;
if (some_fairly_long_condition) {
a = complicated_expression_to_make_foo_1();
} else {
a = complicated_expression_to_make_foo_2();
}
I have two issues with this:
a is a const and should be declared so
the "empty" constructor, Foo() is called for no reason (maybe this is optimised away?)
One way to fix it is by using the ternary operator:
const Foo a = some_fairly_long_condition?
complicated_expression_to_make_foo_1():
complicated_expression_to_make_foo_2();
Is this good practice? How do you go about it?
To answer the second part of your question:
I usually put the initialization code into a lambda:
const Foo a = [&]()->Foo{
if (some_fairly_long_condition) {
return complicated_expression_to_make_foo_1();
} else {
return complicated_expression_to_make_foo_2();
}
}();
In most cases you should even be able to omit the trailing return type, so you can write
const Foo a = [&](){ ...
As far as the first part is concerned:
I'd say that greatly depends on how complex your initialization code is. If all three parts are really complicated expressions (and not just a function call each) then the solution with the ternary operator becomes an unreadable mess, while the lambda method (or a separate named function for that matter) allows you to break up those parts into the respective sub expressions.
If the problem is to avoid ternaty operator and your goal is to define the constant a, this code is an option:
Foo aux;
if (some_fairly_long_condition) {
aux = complicated_expression_to_make_foo_1();
} else {
aux = complicated_expression_to_make_foo_2();
}
const Foo a(aux);
It is a good solution, without any new feature ---as lambdas--- and including the code inline, as you want.

C++ Macro definition including dot?

I have some C++ code that I can't change, only by changing header files. I have the code and can compile it.
The issue is that I have a function pointer defined something like this (function pointer is kind of irrelevant to what I want to do):
foo.bar();
I would like change that with a macro or something to:
#define foo.bar() FunCall()
The issue as I understand is that it is not possible to use dots in a macro, is there any other way?
Edit:
A bit more info. The code I get is intended to run a single instance, however I'm wrapping the code to run multiple instances in a class. That gives some headaches I'm trying to over come.
What I'm trying is either to use a macro and some inline functions or a complete third way:
void function()
{
foo.bar();
}
I need some code that could make above equivalent to:
void class::function()
{
EventFuncTypedef f = foo.bar;
(this->*f)();
}
Or
void class::function()
{
class::FunCall();
}
The code above all work the issue is to try get option 1 or 2 executed by the original code.
with a macro and an helper:
struct FunCaller {
static auto bar() {FunCall();}
};
#define foo FunCaller{}

Dynamically creating a map at compile-time

I'm implementing Lua in a game engine. All of the functions being exported to Lua have headers that start with luavoid, luaint or luabool just for quick reference of the expected parameters, and so I can see at a glance that this function is being exported.
#define luavoid(...) void
luavoid(std::string s) TextMsg()
{
std::string s;
ExtractLuaParams(1, s);
::TextMsg(s.c_str());
}
To actually export a function to Lua, they're added to a dictionary. On startup, the map is used to call lua_register.
std::unordered_map<std::string, ScriptCall> _callMap = {
{ "TextMsg", TextMsg },
...
}
There will be a lot of functions exported. Rather than have to maintain this map manually, I'd like to automate its creation.
My first instinct was something with macros at compile-time. I gave up on it initially and started writing a program to parse the code (as a pre-build event), since all the functions can be text-matched with the luaX macros. It would create a header file with the map automatically generated.
Then I went back to doing it at compile-time after figuring out a way to do it. I came up with this solution as an example before I finally implement it in the game:
using MapType = std::unordered_map<std::string, int>;
template <MapType& m>
struct MapMaker
{
static int MakePair(std::string s, int n)
{
m[s] = n;
return n;
}
};
#define StartMap(map) MapType map
#define AddMapItem(map, s, n) int map##s = MapMaker<map>::MakePair(#s, n)
StartMap(myMap);
AddMapItem(myMap, abc, 1);
AddMapItem(myMap, def, 2);
AddMapItem(myMap, ghi, 3);
void main()
{
for (auto& x : myMap)
{
std::cout << x.first.c_str() << "->" << x.second << std::endl;
}
}
It works.
My question is, how horrible is this and can it be improved? All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
Be gentle(-ish). This is my first attempt at coding with templates like this. I assume this falls under template metaprogramming.
how horrible is this and can it be improved?
Somewhere between hideous and horrendous. (Some questions better left unasked.) And yes...
All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
The simplest thing to do is:
#define ADDFN(FN) { #FN, FN }
std::unordered_map<std::string, ScriptCall> _callMap = {
ADDFN(TextMsg),
...
};
This uses the macros to automate the repetition in the string literal function names and identifiers - there's nothing further substantive added by your implementation.
That said, you could experiment with automating things further than your implementation, perhaps something like this:
#define LUAVOID(FN, ...) \
void FN(); \
static auto addFN ## __LINE__ = myMap.emplace(#FN, FN); \
void FN()
LUAVOID(TextMsg, string s)
{
...
}
See it running here.
The idea here is that the macro generates a function declaration so that it can register the function, then a definition afterwards. __LINE__ likely suffices for uniqueness of the identifiers - assuming you have one file doing this, and that your compiler substitutes a numeric literal (which all compilers I've used do, but I can't remember if the Standard mandates that). The emplace function has a non-void return type so can be used directly to insert to the map.
Be gentle(-ish). This is my first attempt at coding with templates like this.
Sorry.
I assume this falls under template metaprogramming.
It's arguable. Many C++ programmers (myself included) think of "metaprogramming" as involving more advanced template usage - such as variable-length lists of parameters, recursive instantiations, and specialisation - but many others consider all template usage to be "metaprogramming" since the templates provide instructions for how to create instantiations, which is technically sufficient to constitute metaprogramming.

How to force a function to be compiled in C++?

I was just experimenting with C++. I was trying to write a small macro so that all the functions that I define are automatically stored in a map so that I can query, at run time, what functions exist and run them too. The code is as follows:
#include <map>
using namespace std;
typedef void (*funcPointer)();
map <char*, funcPointer> funcList;
#define Function(x) void x() { funcList[#x] = x;
#define End }
I was used funcPointer and End only for easy readability and implementation. Now, I can define a function as
Function(helloWorld)
cout << "Hello World";
End
Now, to read the function names as a list and run all the functions, I use the following code:
int main() {
//helloWorld();
for (map<char*, funcPointer>::iterator I = funcList.begin(); I != funcList.end(); I++) {
printf(I->first);
I->second();
}
getchar();
return 0;
}
The problem is, if I keep the first line of main() (helloWorld();) commented, the compiler doesn't compile the function and skips it for optimization, as according to the compiler, it is never used. So, the function list turns up empty. If, instead, I call the function once, every thing works perfectly, except that it prints "Hello World" twice. Also, I wrote the macro specifically so I do not have to do that.
So, is there any way that I can force the compiler to compile a function even if it is not used?
The problem is that the code to register the function is inside the function, so won't happen unless you call the function. You might instead register it by initialising a global variable, which will happen automatically before main begins. This might look something like
struct funcRegistration {
funcRegistration(char * name, funcPointer func) {funcList[name] = func;}
};
#define Function(x) \
void x(); \
funcRegistration x##_registration(#x, x); \
void x() {
The compiler compiles the function, however your map won't be populated unless its called.
Because funcList[#x] = x; comes inside the function block { } after macro expansion.

Unusual C++ function declaration

There are a few legal ways which can we declare a function in C++.
Some of the legal ways are:
void function ();
void function (void);
dataType function (dataType);
and so on...
Recently, I came across a function declaration as such:
void (function) (); //Take note of the braces around the function name
I have never seen somehting like this before, when I tested it in a C++ compiler, it runs without any warning or compilation errors.
My question is: Why is void (function) (); a legal way to decalre a function prototype? Is there any special meaning to declare a function in this way? Or does it just work normally like any other function declaration?
One difference is that enclosing it in parenthesis prevents the function-like macros expansion by the preprocessor. As mentioned in the other answers it makes no difference though to the actual compiler.
For instance:
// somewhere buried deep in a header
#define function(a, b) a + b
// your code
void function() { // this expands the macro and gives compilation error
}
void (function)() { // this does not expand and works as expected
}
This comes in handy for instance when the bright minds behind the Microsoft Visual Studio library decided to provide function-like macros for things like min and max. (There are other ways like #undef to go around this).
Note that object-like macros (e.g. #define function 3 + 4) are still expanded.
The preprocessor is just a dumb text replacement tool (as opposed to the compiler which is just a (smart) text replacement tool). It takes the macro definition and replaces it everywhere. He is not aware of the semantics of what he replaces.
For instance:
// somewhere buried deep in a header
#define function 3 + 2
// your code
void function() {
}
The preprocessor sees the word function and textually replaces it with the string 3 + 2. He is unaware that function is a id-name part of a function declaration and definition. After the preprocess phase there come the actual compile phases. So the compiler actually sees:
// your code
void 3 + 2() {
}
which does not make any sense to him and gives an error.
For function-like macros
// somewhere buried deep in a header
#define function(a, b) a + b
The preprocessor does the same except that it expects two ‘tokens’ enclosed in parenthesis separated by comma (the parameters) and does the replacement. (again no semantics aware):
int d = function(2, 3);
//will be replaced by the preprocessor to:
int d = 2 + 3; // passes compilation phase
void function();
// the preprocessor doesn’t find the arguments for function so it gives an error.
However if it encounters (function) it will not try to expand it (it ignores it). It is just a rule.
it's the same as
void function();
you can declare it as
void ((function)) ();
if you want :)
be careful not to mix this up with the function pointer declaration syntax.
There is nothing special about it, it means exactly the same as the version without parentheses. It is just an artifact of how the syntax is declared. Usually you see the use of parentheses around the function name when a function pointer is declared, e.g.
void (*function_pointer)() = nullptr;
// a function pointer to a function taking and returning void
in contrast to
void *function();
// a function declaration of a function taking void and returning void*
I think it works the same as a normal function because function pointers are declared like: void (*function)() so if you leave out the * then it should be just a function.
It corresponds to the C++ grammar. If to simplify then one of the rules for defining of the declarator looks as
declarator:
(declarator)
So you can write for example
void (function) ();
or
void ( (function) () );
or even the following way
struct A
{
void ( ( function )() const );
};
I think you may find that was:
void (*function) ();
since there is no benefit to using void (function)(); or void (((((function)))))(); for that matter, they're equivalent. If I'm mistaken and it's not a typo, the answer is that you can put as many parentheses around the function name as you like, subject to compiler limitations, as per the code for output6() below.
If I'm not mistaken, that one with the * actually declares a function pointer which can be used to hold a pointer to a function. It does not declare a function at all, just a pointer that can be used to reference a function.
Like an int pointer (for example), the function pointer can point to an arbitrary function, parameters notwhithstanding.
So for example:
#include <iostream>
void (((((output6)))))() { std::cout << 6; }
void output7() { std::cout << 7; }
void output8() { std::cout << 8; }
void (*fn)();
int main() {
fn = &output6; fn();
fn = &output7; fn();
fn = &output8; fn();
std::cout << '\n';
}
would output 678.