C++ Can I write a function within an expression? [duplicate] - c++

This question already has answers here:
What is a lambda expression in C++11?
(10 answers)
Closed 1 year ago.
I'm writing a (my own language) to C++ transpiler. I'd like to be able to offer a kind of virtual sub function that is transpiled into being part of the C++ code in the same scope in which it is called.
Here is an example of the type of C++ code I'd want to generate:
if (a == {if (getValue(d) == 5) { long r = next(); next(); return r; } else return 0;})
dosomething();
It says if a is equal to the result of what's in the brackets, then dosomething().
You can see the idea is to inline a function within an expression. Yes that could be done by allowing the compiler to inline, but in this case I want to keep access to the variables in the outer scope, which I would lose if it actually were another function.
Any decent way to do this?

If I correctly get what you are doing, you can simply use lambda expression here. This of course requires C++11
if (a ==
[&] () {
if (getValue(d) == 5) {
long r = next();
next();
return r;
} else {
return 0;
}
}()) {
dosomething();
}
If you are writing translator/transpiler you may want to try more explicit capture list than this generic [&].

Related

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

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.

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.

Optional parameter in C++ without overloading [duplicate]

This question already has answers here:
What would be a proper invalid value for a pointer?
(7 answers)
Closed 7 years ago.
I'd like to have a function with an optional parameter but without overloading the function. The reason I don't want to overload is because the function body is quite long, and the version with the optional parameter just differs by a single line.
void myFunction(MyClass my_optional_arg = MyClass())
{
// lots of statements
if (optional_argument_was_passed)
doSomething(my_optional_arg);
// lots more statements
}
int main()
{
myFunction();
MyClass my_optional_object();
myFunction(my_optional_object);
}
The problem that I have with the default parameter route is that I don't know how to check whether the optional parameter was passed or not, i.e., I don't know how to set the boolean flag optional_argument_was_passed. For example, just testing equality of the parameter with the default isn't sufficient because that same default value could be passed into the function. What I'd really like is something like this:
void myFunction(MyClass my_optional_arg = some_unique_null_value)
{
// lots of statements
if (my_optional_arg != some_unique_null_value)
doSomething(my_optional_arg);
// lots more statements
}
It has been suggested that I do something like this:
void myFunction()
{
MyClass my_object();
myFunction(my_object);
}
However, this is not quite what I need; the myFunction(MyClass) function is not necessarily the ultimate function to be used. If I call the function without the optional argument, myFunction(), then I don't want any object of class MyClass to even enter the function at all; rather, the statement that uses this object, called doSomething(MyClass) above, should be omitted.
It has also been suggested that I remove the common parts of both functions to its own function myFunction() and then create an overloaded wrapper function to call the statements with the optional parameter:
void myFunction(MyClass my_optional_arg)
{
doSomething(my_optional_arg);
myFunction();
}
This is a solution, but it would be a bit messy because I have a lot of statements before AND after the doSomething(MyClass) call, so I'd need to split the function into several parts:
void myFunction(MyClass my_optional_arg)
{
myFunctionPartA();
doSomething(my_optional_arg);
myFunctionPartB();
}
void myFunctionPartA()
{
// lots of statements
}
void myFunctionPartB()
{
// lots more statements
}
if the functions are similar then call one from the other. OR have an internal 'do all the work and take all the paramters' function that all the overloads call. This is a very common tactic
void Func() // func with foo defaulting to 42
{
Func(42);
}
void Func(int foo)
{
// one million lines of code
}

C++ Function Pointer

Is this possible? If so, I can't seem to get the syntax right. (C++ function pointer)
bit of background. The code below has been shorten for this post. The reason for this implementation is to avoid an endless list of SWITCH/CASE or IF/ELSEIF statements; and have an endless list of DECODER_FUNCTION_TABLE (see below). This code deals with an industry standard that uses mnemonics to mean different things and there are hundreds of these mnemonics. So this portion of my code is to decode certain mnemonics pass to it from another section of code that loops through a passed in record... anyway my difficulty is in keeping a member function pointer in a structure outside of the class...
Have a look. I think the code may do a better job explaining ;)
typedef struct _DECODER_FUNCTION_RECS
{
ISO_MNEMONIC_ID Mnemonic;
void (Database::*pFn)(Database::Rec *);
}DECODER_FUNCTION_RECS;
DECODER_FUNCTION_RECS DECODER_FUNCTION_TABLE[] = {
SFP, &Database::Decode_SFP,
KOG, &Database::Decode_KOG
};
void Database::DecodedDescription(Rec *A)
{
int i = 0;
bool Found = false;
while( i < DECODER_FUNCTION_TABLE_COUNT && !Found )
{
if( DECODER_FUNCTION_TABLE[i].Mnemonic == A->Mnemonic )
Found = true;
else
i++;
}
if( Found )
(([DECODER_FUNCTION_TABLE[i]).*this.*pFn)( A );
}
void Database::Decode_SFP(Rec *A)
{
// do decode stuff on A
}
The detail I'm trying to work out is this line:
(([DECODER_FUNCTION_TABLE[i]).*this.*pFn)( A );
You call a member function pointer (that's what it's called) with
(this->*DECODER_FUNCTION_TABLE[i].pFn)(A);
Could put parens around DECODER_FUNCTION_TABLE[i].pFn, but the member access operator . has a higher precedence than member function operator ->*.
I wrote up a few simple examples that will shed some light the other day
It's in my answer to this question
error C2664 and C2597 in OpenGL and DevIL in C++
Or a direct link to codepad

Using C++ lambda functions during variable initialisation

I think many of you have this kind of code somewhere:
int foo;
switch (bar) {
case SOMETHING: foo = 5; break;
case STHNELSE: foo = 10; break;
...
}
But this code has some drawbacks:
You can easily forget a "break"
The foo variable is not const while it should be
It's just not beautiful
So I started wondering if there was a way to "improve" this kind of code, and I got this little idea:
const int foo = [&]() -> int {
switch (bar) {
case SOMETHING: return 5;
case STHNELSE: return 10;
...
}
}();
Note: the first pair of parentheses it not mandatory, but MSVC++ doesn't support this yet
You can use the same trick with if-else where the ternary operator would be too complicated, variables that require to be passed by pointers to be initialized (like for DirectX functions), etc.
My questions are:
Is there anything wrong with this code that I didn't see?
Do you find it better than the one above?
g++ seems to inline the function, but do you think that all compilers will do so?
EDIT: this is what I mean by "DirectX functions"
_xAudio2 = [&]() -> std::shared_ptr<IXAudio2> {
IXAudio2* ptr = nullptr;
if (FAILED(XAudio2Create(&ptr, xAudioFlags, XAUDIO2_DEFAULT_PROCESSOR)))
throw std::runtime_error("XAudio2Create failed");
return std::shared_ptr<IXAudio2>(ptr, [](IUnknown* ptr) { ptr->Release(); });
}();
This is a fairly common technique in other languages. Almost every high-level feature of Scheme is defined in terms of lambdas that are immediately called.
In JavaScript it is the basis of the "module pattern", e.g.
var myModule = (function() {
// declare variables and functions (which will be "private")
return {
// populate this object literal with "public" functions
};
})();
So an anonymous function is declared and immediately called, so that any internal details are hidden and only the return value is exposed externally.
The only downsides is that on a casual reading of the code, the return statements will appear to be returning from the outer function (there was intense controversy about this during the Java lambda wars). But this is just something you have to get used to once your language has lambdas.
There are many language features in an imperative language like C++ which would benefit from being able to return a value (rather than being like a void function). For example, if has an alternative, the tertiary operator expr ? a : b.
In Ruby pretty much all statements can be evaluated, so there is no need for a separate syntax where a return value can be supplied. If C++ worked that way, this would mean things like:
auto result = try
{
getIntegerSomehow();
}
catch (const SomeException &)
{
0;
}
I don't see any reason at all to use a switch case in such a case. Any decent compiler will generate just as fast code with if statements as with a switch case.
if(bar == SOMETHING)
foo = 5;
else if(bar == STHNELSE)
foo = 10;