Need a map from enum (class) to std::binary_function - c++

I have this enum (class)
enum class conditional_operator
{
plus_op,
or_op,
not_op
}
And I'd like a std::map that represents these mappings:
std::map<conditional_operator, std::binary_function<bool,bool,bool>> conditional_map =
{ { conditional_operator::plus_op, std::logical_and<bool> },
{ conditional_operator::or_op, std::logical_or<bool>},
{ conditional_operator::not_op, std::binary_negate<bool>} // this seems fishy too, binary_negate is not really what I want :(
Apart from the fact that this doesn't compile:
error: expected primary-expression before '}' token
error: expected primary-expression before '}' token
error: expected primary-expression before '}' token
for each of the three lines, how should I do this? I think a logical_not with a second dummy argument would work, once I get this to compile of course...
EDIT: Could I use lambda's for this?

You really want std::function<bool(bool, bool)>, not std::binary_function<bool, bool, bool>. That only exists for typedefs and stuff in C++03. Secondly, I'd just use a lambda- they're short enough and much clearer. The std::logical_and and stuff only exists for C++03 function object creation, and I'd use a lambda over them any day.
std::map<conditional_operator, std::function<bool(bool,bool)>> conditional_map =
{
{ conditional_operator::plus_op, [](bool a, bool b) { return a && b; } },
{ conditional_operator::or_op, [](bool a, bool b) { return a || b; } },
{ conditional_operator::not_op, [](bool a, bool b) { return !a; } }
};
Wait- what exact operator are you referring to with not? Because that's unary, as far as I know.

#DeadMG’s answer is spot-on but if you insist on using the predefined function objects, you need to instantiate them. At the moment you’re just passing their type names.
That is, you need to write std::logical_***<bool>() instead of just std::logical_***<bool>.

Related

How do I use a Merit function in Gecode?

I am trying to use a merit function for my branching in Gecode. In the MPG, the Gecode Manual, an example merit function is stated, and how to pass it to the branching. But I cannot figure out where to put the function. Should it be inside the script or outside? Right now I have put it next to the copy function, etc. I cannot find any example code where someone uses a merit function.
I get the following error:
program.cpp(247): error C2059: syntax error: '}'
program.cpp(247): error C2853: 'm': a non-static data member cannot have a type that contains 'auto'
program.cpp(259): fatal error C1004: unexpected end-of-file found
This is the code I am trying out:
// ...
branch(*this, workers, BOOL_VAR_MERIT_MIN(m), BOOL_VAL_MAX());
}
auto m = [](const Space& home, BoolVar x, int i) {
return i;
}
// ...
I know it is stupid to make a merit function that just returns the index, I am just trying to make the simplest merit function to work before I do what I want to do.
According to the Gecode documentation the merit function should return a double. As suggested by the type definition of BoolBranchMerit:
typedef std::function<double(const Space& home, BoolVar x, int i)> Gecode::BoolBranchMerit
To be safe, you might also want to declare m as being an Gecode::BoolBranchMerit. So I think the following should fix your example:
// ...
branch(*this, workers, BOOL_VAR_MERIT_MIN(m), BOOL_VAL_MAX());
}
BoolBranchMerit m = [](const Space& home, BoolVar x, int i) -> double {
return (double) i;
}
// ...

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.

template function with pqxx results

This is on os x yosemite with clang from xcode 7.2 in clion.
I'm iterating through a query from a postgresql db and adding the result to a json object.
for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
participants["participants"] += { \
{"id", c[0].as<std::string>()},
{"location", c[1].as<std::string>()},
{"racename", c[2].as<std::string>()},
{"racestart_at", c[3].as<std::string>()},
{"ended_at", static_cast<bool>(c[9].size()) ? c[9].as<std::string>() : ""},
{"racetime", static_cast<bool>(c[10].size()) ? c[10].as<std::string>() : ""}
};
}
Some of the columns have null values so I test for that casting to bool in a ternary operator and either return the result or an empty string. To make it a bit cleaner I tried to add a template function with the example from http://www.cprogramming.com/tutorial/templated_functions.html and had this:
template <class T>
std::string column_content(T a) {
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
}
When I try to compile the program I get the error:
Database.cpp:9:44: error: use 'template' keyword to treat 'as' as a dependent template name
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
^
template
I looked at Cast Chars To Int in Template Function and http://www.cplusplus.com/doc/oldtutorial/templates/ and other suggestions from google but it looks like I'm using the wrong syntax but I can't spot it.
If I could use a template function adding to json could then look like
{"start_at", column_content(c[8])}
regards
Claus
I changed it to a function for the time being. The type passed is pqxx::result::field as per http://pqxx.org/devprojects/libpqxx/doc/2.6.9/html/Reference/a00259.html#2a9d36599b217ebfde2cac4633856ac0.
std::string column_content(pqxx::result::field a) {
if (static_cast<bool>(a.size())) {
return a.as<std::string>();
} else {
return "";
}
}

Downcasting a base class in a container to a derived class

I'll show my code first then explain my issue:
std::vector<std::unique_ptr<SGUIObject> > m_objects;
const std::unique_ptr<SGUIObject>& SGUIManager::getObject(const std::string& object_name)
{
for (auto const& iter : m_objects)
{
if (iter.get()->getObjectName() == object_name)
return iter;
}
}
//SButton is derived from SGUIObject
//m_clicked is a boolean member in SButton (private)
//isClicked is a public member method of SButton
const bool isClicked() const { return m_clicked; }
if (dynamic_cast<SButton>(SSceneManager::getGUIManager().getObject("testbutton").isClicked()))
std::cout << "Clicked!" << std::endl;
I just copy pasted from several different files, so it looks weird when all put together. Anyways, what I'm trying to do is downcast from a SGUIObject to a SButton and call isClicked() in an if/else loop. When I do my current code, Code::Blocks gives me this error:
error: 'const class std::unique_ptr' has no member named 'isClicked'|
I have a feeling I'm having a slight syntactical issue, and I'd be extremely grateful if someone was to explain it to me.
Thanks!
I think you mean:
dynamic_cast<SButton*>(SSceneManager::getGUIManager().getObject("testbutton").get())->isClicked()
You want to call isClicked on the result of the dynamic_cast, not the result of getObject.
This line has several problems:
if (dynamic_cast<SButton*>(SSceneManager::getGUIManager().getObject("testbutton").isClicked()))
First SSceneManager::getGUIManager().getObject("testbutton") return a unique_ptr reference. And as the compiler said, unique_ptr does not hae an isclicked method. For that, you would need to use the -> operator which is overloaded to return the underlying pointer.
Second, even if it worked, you can not dynamic_cast a bool to a pointer.
You could do something like
if (dynamic_cast<SButton*>(SSceneManager::getGUIManager().getObject("testbutton").get())->isClicked) ...
Although you might want to separate it in 2 lines to make sure dynamic_cast does not give you a NULL pointer.
SBButton* button = dynamic_cast<SButton*>(SSceneManager::getGUIManager().getObject("testbutton").get());
if (button && button->isClicked()) ...

ternary operator doesn't work with lambda functions

I am assigning to a std::function<double()> a lambda expression. This snippet works
if(fn_type==exponential)
k.*variable = [=,&k](){ return initial*exp(-k.kstep*par); };
else
k.*variable = [=,&k](){ return initial*pow(k.kstep, par); };
whereas if I want to use the ternary operator
k.*variable = (fn_type==exponential ? [=,&k](){ return initial*exp(-k.kstep*par); } : [=,&k](){ return initial*pow(k.kstep, par); });
I get the following error:
error: no match for ternary ‘operator?:’ in <awfully long template error, because this whole thing is in a class defined in a function...>
Is this a gcc bug (I'm using 4.7.2)? Otherwise why is there this limit in the standard?
The second and third operands of the conditional operator must have the same type or there must be some common type to which they can both be converted that the compiler can figure out. There are only a handful of conversions that the compiler will consider.
Your two lambda expressions have different types, and there is no common type to which they can both be converted (conversions to user-defined types, like std::function<double()>, cannot be considered because there are potentially an infinite number of valid target types).
You can directly convert each of the operands to std::function<double()>:
k.*variable = fn_type==exponential
? std::function<double()>([=,&k](){ return initial*exp(-k.kstep*par); })
: std::function<double()>([=,&k](){ return initial*pow(k.kstep, par); });
But really, it's cleaner with the if/else.
Also faced this issue - won't compile!
'if/else' not good for me, I would like auto type deducing feature turn on.
auto memcpy_traits =
[&](uint8_t* line_dst, const uint8_t* curr_src, const size_t bytes_to_copy) {
std::memcpy(line_dst, curr_src, bytes_to_copy);
line_dst += bytes_to_copy;
curr_src += bytes_to_copy;
}
:
[&](uint8_t* line_dst, const uint8_t* curr_src, const size_t bytes_to_copy) {
std::memcpy(line_dst, curr_src, bytes_to_copy);
line_dst += bytes_to_copy;
curr_src += bytes_to_copy;
};