How can I make a bool reference argument defaulted? - c++

In C++, is it possible to make a bool & argument of a function optional?
void foo(bool &argument = /* What goes here? */);
In my function foo, if the caller does not care about the result put into argument, I'd like the compiler to give a dummy location by default. Otherwise, callers who do not care must do this:
bool ignored;
foo(ignored);

Make another function
void foo(){
bool b=true;
foo(b);
}

The only way is to pass a global variable :
bool someArgument = false;
void foo(bool &argument = someArgument );

Ideally you should be using a function overload instead of trying to work around the system. Although there are legitimate ways to achieve this like the one #VJovic mentioned. With function overloads you can make other parameters optional too if ever you need to add more.

A non-const reference argument means your function intends to modify the object being passed. If you know which object you want that to be by default, then just use it as the default argument.
If you do not intend to modify the bool being passed in, then you should declare the function to take bool argument (i.e. not a reference) or const bool &argument. In either case you can provide a constant default value of true or false.

You can do it. But it is very ugly and messes up data locality:
static bool result__ = false;
static void foo(bool & result = result__)
{
result = true;
}
int main()
{
bool v;
foo();
foo(v);
return v ? 0 : 1;
}
Since C++ supports function overloading, use #QuentinUK's solution.

Related

May I omit a default argument when calling a pointer to a static function?

I'm afraid I'm going to expose my ignorance, but hey, I don't understand this.
If I define a static member function inline like this:
struct S {
static int f(int i = 0) {
return -i;
}
};
and then I take a pointer to S::f:
auto fPtr {&S::f};
int (*fp)(int) {S::f}
either way, it doesn't matter, then I'm not allowed to call it without arguments:
auto a = fPtr(); // error: too few arguments to function
auto b = fp(); // error: too few arguments to function
While instead I can do this:
S s;
auto c = s.f();
which is strange since I thought that, on many levels, static member functions are really not associated to any object, yet they do not work as normal functions if they have default arguments.
I couldn't find any explanation of this behaviour in the Standard, but I'm not really sure that I'm not missing it.

Inserting a function with arguments to appendToGlobalCtors

I want to insert a function call that executes before anything else in the program. I figured the way to do this is to insert to the global constructors with appendToGlobalCtors() in this way:
LLVMContext &C = M.getContext();
Function* FInit = Function::Create(FunctionType::get(Type::getVoidTy(C), false), GlobalValue::ExternalLinkage, INITMEMORY, &M);
appendToGlobalCtors(M, FInit, 0);
This works well if the function has no arguments. But what if the function I need to insert has arguments that I would like to specify? How do I create the function to insert into the global constructors? The function I have returns void. I already know how to use the IRBuilder to create a function call. But the builder takes the arguments in the builder.CreateCall(Func, FuncArgs). How do I do this and append it to the global constructors?
Hope I was clear enough. Let me know if this needs more clarification.
Thanks!
The only way this is possible is when your arguments are constant, obviously. In this case just wrap your call into another function and mark it __attribute__((constructor)):
void foo(int x, int y)
{
...
}
__attribute__((constructor))
void bar()
{
foo(1,2);
}

c++ classes, const function that calls non constant function

in C++ classes, if I have a constant function (In my understanding constant functions are classes that cannot change anyting in the class, hope this is true)
for example a function like this
int output(int value) const
Am I allowed to call a function within this function remove that actually changes anything in the class?
For example lets say I have a variable called number in private.
my output function adds one to the variable number, but not directly, it calls
a non constant function called addOne which adds one to the variable number.
I notice that I am getting an error when a output function is calling addOne(I know that output function is const but it modifies a value, but it modifies it indirectly). I wonder why I am getting an error, what error compiler actually detects here?
Thank You, and sorry if my question is hard to understand.
Thank you all for answering.
The answer is simple - no, you cannot. Every class method is a function that implicitly passes this as a parameter. When you declare a method as const, that means that it will actually pass const this to this function. It is both correct logically and syntactically not to call not const methods from const methods.
const instances can only call const functions. Say:
class YourClass {
...
int output(int value) const;
int regularMethod(); // Non-const
...
};
is your class with a const function. And the variables:
const YourClass obj1;
YourClass obj2;
Here obj1 can call output method while it cant call regularMethod. obj2 can call both.
Every const function() is getting a const this pointer as a default parameter, so you cannot change a member variable of a class even if you try to call a non_cost function from a const function and try to modify a member variable.
So if you try to call a non const function from a const function, you will get compile error.
The answer is NO. The long answer is perhaps YES, provided you use an abomination like this, via const_cast-ing this in the const calling function (but you have to make sure you invoke your function on non-const objects, otherwise it leads to undefined behaviour):
#include <iostream>
struct Foo
{
int x = 0;
void f()
{
++x;
}
void modify_x() const
{
const_cast<Foo*>(this)->f(); // call non-const member function
}
};
int main()
{
Foo foo;
std::cout << foo.x << std::endl;
foo.modify_x();
std::cout << foo.x << std::endl;
}

How to call a function using pointer-to-member-function

I have a class:
class A {
void test_func_0(int);
void run();
typedef void(A::*test_func_t)(int);
struct test_case_t{
test_func_t test_func;
} test_case[100];
};
Now I want to call test_func() inside run():
void A::run()
{
test_case[0].test_func = &test_func_0;
test_case[0].*(test_func)(1);
}
The last line of my code, doesn't work(compile error), no matter what combination I try.
Use this:
void A::run()
{
test_case[0].test_func = &A::test_func_0;
(this->*(test_case[0].test_func))(1);
}
Notice that you had 2 errors. The first one was how you formed the member-function-pointer. Note that the only way to do it is to use &ClassName::FuncName regardless of whether you're at class scope or not. & is mandatory too.
The second is that when you call a member via a member function pointer, you must explicitly specif y the object (of type A in your case) on which to call the member function. In this case you must specify this (and since this is a pointer we use ->* rather than .*)
HTH
Use:
(this->*test_case[0].test_func)(1);
Member function call using pointer-to-member-function:
test_case[0].test_func = &A::test_func_0; //note this also!
(this->*test_case[0].test_func)(1);
Demo : http://www.ideone.com/9o8C4

How do I use an int& parameter with a default value?

I have to add a default int& argument (Eg iNewArgument) to an existing function definition in a header file:
What is the syntax to initialize the last argument to make it take a default value?
..
virtual int ExecNew
(int& param1, int& RowIn,int& RowOut, char* Msg = '0',
bool bDebug=true, int& iNewArgument = NULL ) = 0 ;
.
.
NULL is #defined to 0
Error: default argument: cannot convert from int to int&
Your example indicates that you are creating a virtual function. Default arguments in virtual (especially pure) functions are not a good idea, because they are not considered when you call an overridden function.
struct A {
virtual void f(int = 4711) = 0;
};
struct B : A {
virtual void f(int) { /* ... */ }
};
Now, if someone calls f on a B object, he will have to provide the argument - the default isn't used. You would have to duplicate the default argument in the derived class, which creates ugly redundancies. Instead, you can use the non-virtual interface pattern
struct A {
void f(int a) {
int out;
f(a, out);
}
void f(int a, int &out) {
doF(a, out);
}
protected:
virtual void doF(int a, int out&) = 0;
};
The user can now call f with one, and with two arguments, from whatever class type he calls the function, and the implementers of A don't have to worry about the default argument. By using overloading instead of default arguments, you don't need to break your head around lvalues or temporaries.
The only meaningful way to supply a default argument to a non-const reference is to declare a standalone object with static storage duration and use it as a default argument
int dummy = 0;
...
virtual int ExecNew(/* whatever */, int& iNewArgument = dummy) = 0;
Whether it will work for you or not is for you to decide.
Inside the function, if you'll need to detect whether the default argument was used, you may use address comparison
if (&iNewArgument == &dummy)
/* Default argument was used */
You can't do that. The INewArgument must either be a raw int or a const reference. A non-const reference cannot be used the way you're trying to use it.
In short you're going to have to rework you problem. You can either make your int& a regular int and lose the reference behavior (being able to pass out the changed value) or give up having a default value.
The default has to be lvalue for a non-const reference type, so what try to do above won't work. What you can do is:
namespace detail {
int global;
}
void foo(int &x = detail::global) {}
or
void bar(const int &x = int(3)) {}
You say NULL is #defined to 0, so it's a literal value. The parameter is a reference to an int, which means the function would be able to change the value. How do you change the value of a literal?
You need to make it a const reference, or don't make it a reference at all.