I'm new to c++, and coming from c#;
in c# to achieve my intended goal I would simply do this
public void MyMethod(int? value) {
if(value is null) {
// Do something
} else {
// Do something else
}
}
how might I achieve this result, if possible in c++?
You can do this with std::optional.
void MyMethod(const std::optional<int>& option) {
if(option.has_value()) {
// Do something with the int option.value()
} else {
// Do something else with no value.
}
}
std::nullopt is what you pass when no value is desired. MyMethod(std::nullopt);
Or if you want to be able to omit the argument entirely and say MyMethod() then you can make the argument default to std::nullopt.
void MyMethod(const std::optional<int>& option = std::nullopt) {
This sounds like a job for overloading:
void f() {
// do something for no argument
}
void f(int i) {
// do something with I
}
Related
I'm trying to modify a bool field in a method. The method accepts a pointer pointer bool, but can't seem to figure it out how to do this correctly.
This is a basic example of something similar I want to do:
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(&seenWarningA)
}
void pushWarning(bool ** warning) {
**warning = true;
}
}
This code example errors (sending bool* but needs to be bool**) and I've tried other ways with no luck. Can't find any online examples but maybe I'm searching for the wrong terms. What is the right way to do this?
Since you have a class, no parameters are required.
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning()
}
void pushWarning() {
seenWarningA = true;
}
}
Using references rather than pointers is more elegant.
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(seenWarningA)
}
void pushWarning(bool & warning) {
warning = true;
}
}
If you want to use pointers, the & operator just gives single pointer rather than a double point:
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(&seenWarningA)
}
void pushWarning(bool * warning) {
*warning = true;
}
}
You appear to be trying to pass an argument of bool* into a function that takes bool**. Remove one of the layers of indirection from the parameter list, or add one to the value you're passing in. Either should work.
Two mistakes:
First- your declaration of pushWarning is with parameter of type bool**, and you are trying to send bool*.
Second- you can simply use reference:
using namespace std;
class WarningManager {
public:
bool seenWarningA;
void updateWarnings() {
pushWarning(seenWarningA);
}
void pushWarning(bool &warning) { // You can simply use refference instead of pointer to pointer, or pointer at all..
warning = true;
}
};
int main()
{
WarningManager w;
w.seenWarningA = false;
w.updateWarnings();
cout << w.seenWarningA; // Prints 1
return 0;
}
If I have some code like this:
void function_1(...)
{
//do something
}
void function_2(...)
{
//do something
}
int function_3(...)
{
//do something
}
int main()
{
....
if (CONSTANT_1) function_1()
else if (CONSTANT_2) function_2()
else if (CONSTANT_3) function_3()
....
}
I would like avoid the if-else statement and do something like this in main function:
int main()
{
function<CONSTANT>();
}
How can I avoid the use of if-else statement and simulate this behavior?
In general you can specialize the function template:
template<int N>
void function();
template<>
void function<1>()
{
//do something
}
template<>
void function<2>()
{
//do something
}
template<>
void function<3>()
{
//do something
}
This works, but there might be better solutions as well.
Overload and tag dispatch. The Base template will convert the constant into a unique type. Then simple overload resolution will choose the proper overload. This is all assuming the constant are constexpr, and not something known only at run-time.
void function(std::integral_constant<int, CONSTANT_1>)
{
//do something
}
void function(std::integral_constant<int, CONSTANT_2>)
{
//do something
}
int function(std::integral_constant<int, CONSTANT_3>)
{
//do something
}
template<int constant>
auto function()
{
return function(std::integral_constant<int, constant>{});
}
int main()
{
function<CONSTANT_2>(); // calls the second overload
}
The above has the benefit of issuing a compile time error when an overload isn't found, as opposed to a linkage error if you specialize template functions instead.
This might sound a little convoluted, but here we go.
So, I have the following code:
void Utility::validateRangeAndModify(Pet pet, int checkint,
int numbertovalidate,
bool greaterorless)
{
if (greaterorless) {
if (numbertovalidate < checkint)
pet.getAttributes()->setPetHunger(0);
} else
if (numbertovalidate > checkint)
pet.getAttributes()->func(100);
}
Firstly, This code is designed to validate a single integer. That part is easy.
Then, what I want it to do is carry out a function depending on if the integer meets the condition or not. In this case, setPetHunger() is being set to either 0 or 100. The issue is, I have setPetHealth(), and setPetEnergy() too.
The function I want it to perform is the thing that I want to change.
For instance. This code will only work for my pets Hunger. It won't work for it's Health, Happiness, or any of it's other variables. and I have a ton of other variables.
I'm wondering if there is any way to achieve something like this:
void Utility::validateRangeAndModify(Pet pet,
int checkint,
int numbertovalidate,
bool greaterorless,
string functiontouse)
{
if (greaterorless) {
if (numbertovalidate < checkint)
pet.getAttributes()->setPetHunger(0);
} else
if (numbertovalidate > checkint)
pet.getAttributes()->FUNCTION_TO_USE(100);
}
I could use something like reflection for this in C#. However, I don't know an alternative function in c++
You can do it by passing the correct member function pointer as parameter to Utility::validateRangeAndModify as below:
void
Utility::validateRangeAndModify(Pet &pet, int checkint, int numbertovalidate,
bool greaterorless, void(Attrib::*memfun)(int)) {
^^^^^^^^^^^^^^^^^^^^^^^^^^
if(greaterorless) {
if(numbertovalidate < checkint) (pet.getAttributes()->*memfun)(0);
} else {
if(numbertovalidate < checkint) (pet.getAttributes()->*memfun)(100);
}
}
And then call it as (if Utility::validateRangeAndModify is not static use obj.validateRangeAndModify):
Utility::validateRangeAndModify(p, 10, 9, false, &Attrib::setPetHunger);
Utility::validateRangeAndModify(p, 10, 9, false, &Attrib::setPetThirst);
LIVE DEMO
You should use a function pointer:
void Utility::validateRangeAndModify(Pet pet, int checkint,
int numbertovalidate,
bool greaterorless,
void (*func)(int, attribs &))
{
if (greaterorless) {
if (numbertovalidate < checkint)
pet.getAttributes()->setPetHunger(0);
} else
if (numbertovalidate > checkint)
func(100, pet.getAttribs());
}
You and the client will agree on the prototype of the function that you will pass; in this case, the prototype will be void func(int, attribs &);
The client can write code like this:
void happiness(int level, attribs &a)
{
// some code here
}
Utility::validateRangeAndModify(..., happiness);
Now happiness willl be called by your validateRangeAndModify function.
NOTE: happiness is a free function. If it is a member function, mark it as static: then there won't be the extra this argument.
To keep this simple, I'm providing a really trivial program that uses std::bind, std::function, and std::placeholders to allow calls to a bound method. This keeps the correct this with the method and generally prevents nastiness.
#include <iostream>
#include <functional>
// bait class to catch bound function calls. Replace this with pet for OP's example
class TwoMethods
{
public:
void method1(int val)
{
std::cout << "Method 1 received " << val << std::endl;
}
void method2(int val)
{
std::cout << "Method 2 received " << val << std::endl;
}
};
// utility function that will operate on a bound function
void utilityfunction(std::function<void(int)> func)
{
// calls passed function. Quietly handles bound this parameter and replaces
// placeholder with 42
func(42);
}
int main()
{
TwoMethods obj;
// call utility function with appropriate object and method
// the std::placeholders::_1 lets the compiler know there is another parameter that
// will be supplied later
utilityfunction(std::bind(&TwoMethods::method1, obj, std::placeholders::_1));
utilityfunction(std::bind(&TwoMethods::method2, obj, std::placeholders::_1));
}
In OP's case:
void Utility::validateRangeAndModify(int checkint,
int numbertovalidate,
bool greaterorless,
std::function<void(int)> func)
{
switch (greaterorless)
{
case 0:
{
if (numbertovalidate < checkint)
{
func(0);
}
}
break;
case 1:
{
if (numbertovalidate > checkint)
{
func(100);
}
break;
}
}
}
And called something like:
validateRangeAndModify(42, 666, false,
std::bind(&Attributes::setPetHunger,
pet.getAttributes(),
std::placeholders::_1))
Let's say I have this function template:
void bar(T)(T obj) {
// ...
}
I'd like to change the behavior of the function if T is some Nullable!U, so that if obj.isNull is true, I do some alternate flow, or otherwise continue as if a plain U type had been passed instead.
void bar(T)(T obj) {
static if(is(T == Nullable!U)) { // ?
if(obj.isNull) {
writeln("Object was null!");
return;
}
auto realObj = obj.get;
} else {
alias realObj = obj;
}
writeln("Object was "~to!string(realObj));
}
Is there a way to check if T is an instance of Nullable, and if so, get the wrapped type?
Or more generally, is there a way to check if type T is an instantiation of some template Foo, and get the template parameters if so?
You can provide a specific overload for Nullables:
void bar(T : Nullable!U, U)(T obj) {
if (obj.isNull) {
writeln("Object was null!");
return;
}
bar(obj.get);
}
void bar(T)(T obj) {
writeln("Object was "~to!string(obj));
}
Your code is mostly correct, all you need is to change this line:
static if(is(T == Nullable!U))
to this
static if(is(T == Nullable!U, U)), and U will be aliased to the type of the Nullable (i.e. int, ...)
Code: http://dpaste.dzfl.pl/cc225c8d4ca3
I have a vector populated with callback functions and I would like to check whether callback to the function already exists prior to adding it. I don't know whether it will even work bu so far it doesn't even compile.
vector<std::function<void(void*)>> _callbacks;
void Event::RegisterCallback(std::function<void(void*)> callback)
{
if (callback == NULL)
return;
vector<std::function<void(void*)>>::iterator it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end())
{
_callbacks.push_back(callback);
}
else
{
//print error
throw;
}
}
This gives a compile error:
"Overload resolution selected deleted operator '=='" in alorithm(805). This is related to the find function call.
How do I get this to work and is it even going to compare function calls to the same method properly?
Thanks
As noted in the comments the simplest solution is to use default C-style function pointers as they support == operator in opposite to C++11 function which does not.
using func_type = void(*)();
vector<func_type> _callbacks;
void Event::RegisterCallback(func_type callback)
{
if (callback == nullptr)
return;
auto it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end()) {
_callbacks.push_back(callback);
}
else {
throw;
}
}
void f() {};
void g() {};
/*
evt.RegisterCallback(f); // works fine
evt.RegisterCallback(g); // works fine
evt.RegisterCallback(f); // throws exception
*/
If you don't like this approach you can write your own function-pointer class with support of equality operator.
Another solution is to have a class with a std::function member and another comperable member, and then overloading the () to get the std::function parameter and call it with the parameter, and the == operator to compeare the class using the comperable member.
CompareableFunction.h:
class CompareableFunction
{
public:
CompareableFunction(int nId, std::function<void(parameter)> handler);
~CompareableFunction();
void operator()(parameter param);
bool operator== (CompareableFunction compareableFunc);
private:
std::function<void(parameter)> m_handler;
int m_nId;
};
CompareableFunction.cpp:
CompareableFunction::CompareableFunction(int nId, std::function<void(parameter)> handler)
{
m_nId = nId;
m_handler = handler;
}
CompareableFunction::~CompareableFunction()
{
}
void CompareableFunction::operator()(parameter param)
{
return m_handler(param);
}
bool CompareableFunction::operator==(CompareableFunction compareableFunc)
{
return (m_nId == compareableFunc.m_nId);
}
EDIT: you can convert the std::function to a C-style function pointer and use it to compare. example to a conversion is here: http://www.cplusplus.com/forum/general/63552/