function-style-cast in Template Meta programming - c++

Code taken from the book Template Metaprogramming with C++, it doesn't compile i tried visual studio 22 i get the error:
Error C2440
\<function-style-cast\>'
: cannot convert from 'initializer list' to 'n713::async_bool'chapter_07
see code:
class async_bool{
std::function<bool()> check;
public:explicit async_bool() = delete;
async_bool(std::function<bool()> checkIt): check(checkIt){ }
async_bool(bool val)
: check([val]() {return val; })
{ }
static async_bool yes() {
return async_bool(
[]() { return true; } );
}
static async_bool no() {
return async_bool(
[]() { return false; } );
}
bool operator&&(bool fore) const { return fore && check(); }
bool operator!() const { return !check(); }
operator bool() const { return check(); }
};
int main(){
async_bool b1 = async_bool(false); //async_bool b1{ false };
async_bool b2 = async_bool(true);// async_bool b2{ true };
async_bool b3{ {std::cout << "Y/N? "; char c; std::cin >> c; return c == 'Y' || c == 'y'; }
if (b1) { std::cout << "b1 is true\n"; }
if (b2) { std::cout << "b2 is true\n"; }
if (b3) { std::cout << "b3 is true\n"; }
return 0;
};
tried c++20 with visual studio
tried g++ in ubuntu-> gave different errors but still didnt compile, managed to fix it i think by changing the code to the following:
class async_bool
{
using check = std::function<bool()>;
check dec_;
public:
async_bool() = delete;
async_bool(check dec) : dec_{ std::move(dec) } {}
async_bool(bool val) :dec_([val]() {return val; }) {}
static async_bool yes() {
const auto lam = []() { return true; };
async_bool async_bool_yes(lam());
return async_bool_yes;
}
static async_bool no() {
const auto lam = []() { return false; };
async_bool async_bool_no(lam());
return async_bool_no;
}
bool operator&&(bool fore) const { return fore && dec_(); }
bool operator!() const { return !dec_(); }
operator bool() const { return dec_(); }
};
and in main:
int main()
{
async_bool b1( false );
async_bool b2{ true };
const auto lam = []() { []() {std::cout << "Y/N? "; char c; std::cin >> c; return c == 'Y' || c == 'y'; }; };
async_bool b3{lam};
return 0;
}

Lambdas that don't capture anything are convertible both to std::function and to bool (via conversion to function pointer). You can add an additional templated constructor to make compiler prefer conversion to std::function:
template <typename F,
typename = std::enable_if_t<std::is_convertible_v<F,std::function<bool()>>>>
async_bool(F checkIt): check(checkIt) { }
Alternatively, instead of SFINAE you can use concepts.
(Edit: it's interesting that removing the constructor from std::function removes the ambiguity, but every construction with a { <captureless-lambda> } still fails because conversion from a function pointer to a bool is forbidden using braces, but the corresponding candidate it is not removed from overload-set. Maybe language lawyers can explain this bit if you're interested.

Related

How to return an std::optional lambda?

How can I declare a function that returns an std::optional lambda? e.g.
<what_do_i_put_here?> foo(bool b) {
if(b) return std::nullopt;
return [](int) { ... };
}
How about using the ternary operator? It will automatically deduce the correct optional type
#include <optional>
auto foo(bool b) {
return b ? std::nullopt : std::optional{[](int){}};
}
You can add a level of indirection to deduce the type via auto and decltype:
#include <optional>
auto foo_impl(){
return [](int){};
}
std::optional<decltype(foo_impl())> foo(bool b) {
if(b) return std::nullopt;
return foo_impl();
}
You can do it something like the following
#include <iostream>
#include <optional>
auto f( bool b )
{
auto l = [] { std::cout << "Hello World!"; };
std::optional<decltype( l )> opt;
if (b)
{
// some code
opt = l;
}
else
{
// some other cod
}
return opt;
}
int main()
{
( *f( true ) )( );
}
Another way is to use std::function with std::optional as for example
std::optional<std::function<void( int )>> g( bool b )
{
if (b)
{
return std::function<void( int )>( []( int x ) { std::cout << x; } );
}
else
{
return std::function<void( int )>( []( int x ) { std::cout << 2 * x; } );
}
}
In the upcoming C++23 you can avoid an extra function while only constructing your lambda in case it is needed. Unfortunately, support for this is currently experimental:
#include <optional>
auto foo(bool const b) {
return (b ? std::optional<bool>(true) : std::optional<bool>())
.transform([](bool){
return [](int){ return 42;};
});
}
(demo with gcc trunk)
This uses the new std::optional<T>::transform(F) member function.

Fast computation of logic gates

I created the following code to compute the result of a logic gate (AND, OR, NOT). The function will be used in a circuit simulation where the circuits are read from a netlist file. A circuit could consist of up to 50000 logic gates.
Based on the fact that this function is often called during the simulation I would like to know if it could be implemented in another way so the generated machine code would be more efficient?
A logic gate could have more than two inputs (except NOT with only one input) but most logic gates have only two. So I thought about testing for two inputs and then write something like this: return input->predecessors[0]->result && return input->predecessors[1]->result; and return input->predecessors[0]->result || return input->predecessors[1]->result; But this would probably introduce new branches. The number of the inputs could be stored in the Node directly to prevent the call of the size() method.
#include <vector>
enum class NodeType { NOT, AND, OR };
struct Node {
NodeType type;
bool result;
std::vector<Node *> predecessors;
};
bool evaluate(Node *input) {
switch (input->type) {
case NodeType::NOT: {
return !input->predecessors[0]->result;
}
case NodeType::AND: {
bool result = true;
for (const auto &node : input->predecessors) {
result = result && node->result;
}
return result;
}
case NodeType::OR: {
bool result = false;
for (const auto &node : input->predecessors) {
result = result || node->result;
}
return result;
}
};
};
I'd be tempted to get the first input and merge its state into the switch(); like:
bool result = input->predecessors[0];
switch((input->type << 1) | result) {
case (NodeType::NOT << 1) | false:
return true;
case (NodeType::NOT << 1) | true:
return false;
case (NodeType::AND << 1) | false:
return false;
case (NodeType::OR << 1) | true:
return true;
case (NodeType::AND << 1) | true: {
for (const auto &node : input->predecessors) { // Note: Can skip 1st iteration
result = result && node->result;
if(result == false) {
return false;
}
}
return true;
}
case (NodeType::OR << 1) | false:
for (const auto &node : input->predecessors) { // Note: Can skip 1st iteration
result = result || node->result;
if(result == true) {
return true;
}
}
return false;
}
The hope being that the compiler will be able to convert this into a jump table (e.g. a single "jmp [table+rax*8]" instruction replacing all the switch() and half the rest of the code).
WARNING: For this to work you have to make sure that input->predecessors[0] uses 1 for "true" (and that no other value is used for true). If that is a potential concern; you can use bool result = !!input->predecessors[0];
It really looks like what you are doing is an interface.
struct Node {
std::vector<Node *> predecessors;
virtual bool evaluate() const;
};
struct NodeNot : Node {
bool evaluate() const {
return !input->predecessors[0]->result;
}
};
struct NodeAnd : Node {
bool evaluate() const {
for (const auto &node : input->predecessors) {
if(!node->result) {
// there is no need to accumulate the result
// fail fast
return false;
}
}
return true;
}
};
struct NodeOr : Node {
bool evaluate() const {
for (const auto &node : input->predecessors) {
if (node->result) {
return true;
}
}
return false;
}
};
That way you eliminate the need for the switch completely and achieve same result with just a single virtual call. It may be faster or slower method then the switch, it really depends on many factors and how good you are caching the result in Node::result member. Profile your code to be sure what works best.
I was looking at using std::variant. Still a bit hacky, because I'm using void pointers... any help on cleaning this up would be nice
#include <tuple>
#include <variant>
#include <stdexcept>
#include <assert.h>
using vcpc = void const* const;
struct NOT { vcpc ptr; };
struct OR { vcpc ptr1; vcpc ptr2; };
struct AND { vcpc ptr1; vcpc ptr2; };
using Node = std::variant<NOT, OR, AND, bool>;
// from https://en.cppreference.com/w/cpp/utility/variant/visit
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;
using Ncpc = Node const* const;
constexpr bool evaluate(Ncpc input) {
return std::visit(overloaded{
[](NOT const& arg) { return !evaluate((Ncpc)arg.ptr); },
[](OR const& arg) { return evaluate((Ncpc)arg.ptr1) || evaluate((Ncpc)arg.ptr2); },
[](AND const& arg) { return evaluate((Ncpc)arg.ptr1) && evaluate((Ncpc)arg.ptr2); },
[](bool arg) { return arg; },
}, *input);
}
int main() {
Node const isTrue{ true };
Node const invTrue{ NOT{&isTrue} };
assert(evaluate(&invTrue) == false);
Node const andTrueFalse{ AND{&isTrue, &invTrue} };
assert(evaluate(&andTrueFalse) == false);
Node const orTrueFalse{ OR{&isTrue, &andTrueFalse} };
assert(evaluate(&orTrueFalse) == true);
}

How to say Hello World with C++20 coroutine?

Just for learning purpose I've tried to make overcomplicated "Hello World" program with C++20 coroutines:
HelloWorldMessage sayHelloToWorld()
{
co_yield "Hello";
co_yield " ";
co_yield "World";
co_yield "!";
}
int main()
{
for (auto w : sayHelloToWorld())
{
std::cout << w;
}
}
To prepare such HelloWorldMessage generator I based mainly on latest clang warning messages and, uncomplete cppreference page and this example.
So my result below. What is missing here? Because, instead of saying Hello, I got segmentation fault:
See link:
struct HelloWorldState
{
const char* currentWord = "<not value yet>";
bool finalWord = false;
};
struct HelloWorldPromise
{
HelloWorldState state;
std::experimental::suspend_always initial_suspend() const noexcept { return {}; }
std::experimental::suspend_always final_suspend() const noexcept { return {}; }
std::experimental::suspend_always yield_value(const char* word) noexcept
{
state.currentWord = word;
return {};
}
std::experimental::suspend_always return_void() noexcept
{
state.finalWord = true;
return {};
}
auto& get_return_object() noexcept
{
return *this;
}
void unhandled_exception()
{
state.finalWord = true;
throw;
}
};
struct HelloWorldMessage
{
using promise_type = HelloWorldPromise;
using promise_handle = std::experimental::coroutine_handle<promise_type>;
struct Iter
{
promise_handle handle = nullptr;
HelloWorldState state;
using iterator_category = std::input_iterator_tag;
using value_type = const char*;
using difference_type = ptrdiff_t;
using pointer = value_type const *;
using reference = value_type const &;
reference operator * () const { assert(handle); return state.currentWord; }
pointer operator -> () const { return std::addressof(operator*()); }
bool operator == (const Iter& other) { return handle == other.handle; }
bool operator != (const Iter& other) { return !(*this == other); }
Iter() = default;
Iter(promise_handle handle)
: handle(handle)
{
assert(handle);
next();
}
Iter& operator ++()
{
if (!handle)
return *this;
if (state.finalWord)
{
handle = nullptr;
return *this;
}
next();
return *this;
}
void next()
{
try {
handle.resume();
state = handle.promise().state;
} catch (...) {
std::cerr << "#%$##%##$% \n";
}
}
};
promise_handle handle = nullptr;
HelloWorldMessage(promise_type& promise) : handle(promise_handle::from_promise(promise)) {}
Iter begin() const { assert(handle); return {handle}; }
Iter end() const { return {}; }
};
Maybe clang is not ready yet?
A few mistakes:
First - promise shall return generator object, not reference to itself. So the proper way is:
struct HelloWorldPromise
{
...
auto get_return_object();
...
};
struct HelloWorldMessage
{
...
};
auto HelloWorldPromise::get_return_object()
{
return HelloWorldMessage(*this);
}
Next - terminate and return void can be simplified to:
void return_void() noexcept
{}
void unhandled_exception()
{
std::terminate();
}
Next - in iterator - we shall rely on handle.done - so the state.finalWord is not needed. Full iterator source is:
struct Iter
{
promise_handle handle = nullptr;
HelloWorldState state;
reference operator * () const { return state.currentWord; }
pointer operator -> () const { return std::addressof(operator*()); }
bool operator == (const Iter& other) const { return !handle == !other.handle; }
bool operator != (const Iter& other) const { return !(*this == other); }
Iter() = default;
Iter(promise_handle handle)
: handle(handle)
{
next();
}
Iter& operator ++()
{
if (!handle)
return *this;
next();
return *this;
}
void next()
{
if (!handle)
return;
try {
handle.resume();
if (!handle.done())
state = handle.promise().state;
else {
handle = nullptr;
}
} catch (...) {
std::cerr << "#%$##%##$% \n";
}
}
};
And full working example here.
I take most of my corrections from this 2018/n4736.pdf.

Is it possible to define a variable that can be set only once?

I know of const, that can't be changed after creation. But I was wondering if there is a way to declare a variable that you set only once and after that, can't overwrite.
In my code, I would like to avoid the bool variable by having an nFirst that, once set to nIdx, can't be set to the new value of nIdx.
My code:
int nFirst = 0;
int nIdx = 0;
bool bFound = false;
BOOST_FOREACH(Foo* pFoo, aArray)
{
if (pFoo!= NULL)
{
pFoo->DoSmth();
if (!bFound)
{
nFirst= nIdx;
bFound = true;
}
}
nIdx++;
}
Pretty easy to roll your own.
template<typename T>
class SetOnce
{
public:
SetOnce(T init) : m_Val(init)
{}
SetOnce<T>& operator=(const T& other)
{
std::call_once(m_OnceFlag, [&]()
{
m_Val = other;
});
return *this;
}
const T& get() { return m_Val; }
private:
T m_Val;
std::once_flag m_OnceFlag;
};
Then just use the wrapper class for your variable.
SetOnce<int> nFirst(0);
nFirst= 1;
nFirst= 2;
nFirst= 3;
std::cout << nFirst.get() << std::endl;
Outputs:
1
I would like to avoid the bool variable
You can check nFirst itself, based on the fact that it won't be set a negative number. Such as:
int nFirst = -1;
int nIdx = 0;
BOOST_FOREACH(Foo* pFoo, aArray)
{
if (pFoo != NULL)
{
pFoo->DoSmth();
if (nFirst == -1)
{
nFirst = nIdx;
}
}
nIdx++;
}
Similar to cocarin's, but throws exception instead of silently ignoring assignment:
template <typename T, typename Counter = unsigned char>
class SetOnce {
public:
SetOnce(const T& initval = T(), const Counter& initcount = 1):
val(initval), counter(initcount) {}
SetOnce(const SetOnce&) = default;
SetOnce<T, Counter>& operator=(const T& newval) {
if (counter) {
--counter;
val = newval;
return *this;
}
else throw "Some error";
}
operator const T&() const { return val; } // "getter"
protected:
T val;
Counter counter;
};
Usage:
SetOnce<int> x = 42;
std::cout << x << '\n'; // => 42
x = 4;
// x = 5; // fails
std::cout << x << '\n'; // => 4
Online demo
Your question is about avoiding the bool but also implies the need for const-ness.
To avoid the bool, I'd use a boost::optional like this:
boost::optional<int> nFirst;
// ..
if (!nFirst) nFirst = nIdx;
// and now you can use *nFirst to get its value
Then, you can enforce logical (rather than literal) const-ness like this:
const boost::optional<int> nFirst;
// ..
if (!nFirst) const_cast<boost::optional<int>&>(nFirst) = nIdx;
// you can use *nFirst to get the value, any attempt to change it would cause a compile-time error
Using const_cast is not the safest practice, but in your particular case and as long as you only do it once it'd be OK. It simplifies both your code and your intentions: you do want a const, it's just that you want to defer it's initialisation for a bit.
Now, as songyuanyao suggested, you could directly use an int instead of a boost::optional, but the latter makes your intention explicit so I think it's better this way. In the end of day this is C++ while songyuanyao's solution is really a C-style one.
This is set once template. You can use this class as assurance that the value will be set and saved only once. Every next try will be canceled.
#include <iostream>
using namespace std;
template <class T>
class SetOnce;
template<class T>
std::ostream& operator<<( ostream& os, const SetOnce<T>& Obj );
template <class T>
class SetOnce
{
public:
SetOnce() {set = false; }
~SetOnce() {}
void SetValue(T newValue) { value = !set ? newValue : value; set = true; }
private:
T value;
bool set;
friend std::ostream& operator<< <>( ostream& os, const SetOnce& Obj );
public:
SetOnce<T>& operator=( const T& newValue )
{
this->SetValue(newValue);
return *this;
}
};
template<class T>
std::ostream& operator<<( ostream& os, const SetOnce<T>& Obj )
{
os << Obj.value;
return os;
}
Use case:
int main()
{
SetOnce<bool> bvar;
SetOnce<int> ivar;
SetOnce<std::string> strvar;
std::cout<<"initial values: \n"<<bvar<<" "
<<ivar<<" "<<strvar<<" \n\n";
bvar = false; //bvar.SetValue(false);
ivar = 45; //ivar.SetValue(45);
strvar = "Darth Vader"; //strvar.SetValue("Darth Vader");
std::cout<<"set values: \n"<<bvar<<" "
<<ivar<<" "<<strvar<<" \n\n";
bvar = true; //bvar.SetValue(true);
ivar = 0; //ivar.SetValue(0);
strvar = "Anakin"; //strvar.SetValue("Anakin");
std::cout<<"set again values: \n"<<bvar<<" "
<<ivar<<" "<<strvar<<" \n\n";
return 0;
}

How to avoid forgetting to define operator== in subclasses?

I have a base class and define a operator== on it. And B is a subclass of A and I forget to define operator== on B. Then A::operator== is used on comparing B and usually this gives an unexpected results. Any good method to avoid such "forget"? I add an example to clarify my question.
class A
{
public:
bool operator==(const A& rhs) const
{
return i == rhs.i;
}
int i
};
class B : public A
{
public:
int j;
}
B b1, b2;
b1.i = 1; b1.j = 2;
b2.i = 1; b1.j = 3;
bool b = (b1 == b2); // will be true
What you could try is put A in a namespace, create operator == as a template non-member also in that namespace and let ADL take care of it.
#include <iostream>
namespace stuff {
class A
{
};
class B : public A {};
template <typename T>
bool operator == (const T &lhs, const T &rhs)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return &lhs == &rhs; // <-- replace this with something real
}
}
struct C {};
int main()
{
stuff::A a, aa;
stuff::B b, bb;
C c, cc;
b == bb;
aa == a;
aa == cc; // error: no match for "operator==" stuff::A and C
b == a; // error: no match for "operator==" stuff::B and stuff::A
}
Edit: For your edited example where you want the equality check to compare each part of the class with the other respective corresponding part, DyP's suggestion can work. For example:
// same as before
// ...
class A
{
public:
bool is_equal(const A &rhs) const { return i == rhs.i; }
};
class B : public A
{
public:
bool is_equal(const B &rhs) const { return A::is_equal(rhs) && (j == rhs.j); }
};
template <typename T>
bool operator == (const T &lhs, const T &rhs)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return lhs.is_equal(rhs);
}
Now comparing this again in the using code:
// ...
b.i = 1, bb.i = 1;
b.j = 1, bb.j = 42;
cout << boolalpha << (b == bb) << '\n';
b.j = 42;
cout << (b == bb) << '\n';
a.i = 2, aa.i = 3;
cout << (aa == a) << '\n';
outputs:
bool stuff::operator==(const T&, const T&) [with T = stuff::B]
false
bool stuff::operator==(const T&, const T&) [with T = stuff::B]
true
bool stuff::operator==(const T&, const T&) [with T = stuff::A]
false
Allowing implicit conversions for greatwolf's great approach is a bit tricky:
#include <type_traits>
namespace stuff
{
template<class T, class U>
bool operator== (const T &lhs, const U &rhs)
{
using namespace std;
static_assert(is_convertible<T, U>{} || is_convertible<U, T>{},
"invalid argument type");
static_assert
(
is_same<T, U>{}
|| ( not is_base_of<T, U>{} && not is_base_of<U, T>{})
, "use explicit casts to compare derived to base class types"
);
return is_equal(lhs, rhs);
}
template<class T>
bool is_equal(T const&, T const&)
{
// force compile-time failure when instantiating
static_assert(std::is_same<T, void>{},
"no free is_equal function for these argument types available");
return false;
}
class A
{
private:
int i;
friend bool is_equal(A const& lhs, A const& rhs)
{ return lhs.i == rhs.i; }
public:
A(int p_i) : i(p_i) {}
};
class B : public A
{
int j;
public:
B(int p_i, int p_j) : A(p_i), j(p_j) {}
};
class C : public A
{
private:
int j;
friend bool is_equal(C const& lhs, C const& rhs)
{
return is_equal(static_cast<A const&>(rhs),
static_cast<A const&>(lhs))
&& lhs.j == rhs.j;
}
public:
C(int p_i, int p_j) : A(p_i), j(p_j) {}
};
}
struct D
{
operator stuff::C() const
{
return stuff::C(1, 42);
}
};
#include <iostream>
int main()
{
stuff::A a(1), aa(1);
stuff::B b(1, 42), bb(1, 42);
stuff::C c(1, 42), cc(1, 42);
D d;
// commented lines invoke compilation failures
std::cout << "a == aa: " << (a == aa) << std::endl;
//std::cout << "a == b : " << (a == b ) << std::endl;
//std::cout << "b == bb: " << (b == bb) << std::endl;
//std::cout << "a == c : " << (a == c ) << std::endl;
std::cout << "c == cc: " << (c == cc) << std::endl;
std::cout << "d == c : " << (d == c ) << std::endl;
}
Why do you have equality comparison in a class hierarchy? In many cases, this indicates a problem with the design, with classes that don't properly behave like value types, but not properly like objects from a hierarchy either.