Deriving from std::function vs creating a functor manually - functor

I am trying to create a queue of callable elements with state so I can store the callable element (with an integer indicating when it should be called) and then call it later (after checking the stored integer within it).
I have been reading about functors and the std::function template for the past few days and I am wondering which one of the following two options would be better in terms of both memory and performance (which is better for each, if different).
1st Option:
class UpdateFunction : public std::function<bool(unsigned long long int)> {
public:
unsigned long long int _intendedTime;
};
void main()
{
typedef std::deque<UpdateFunction> UpdateQueue;
UpdateQueue _updateQueue;
_updateQueue.push_back(UpdateFunction([](unsigned long long int time)->bool{return outsideFunction(time);}));
_updateQueue.back()._intendedTime = 10;
}
2nd Option:
class UpdateFunction {
bool (*_fn)(unsigned long long int);
unsigned long long int _intendedTime;
UpdateFunction::UpdateFunction(bool (*fn)(unsigned long long int), unsigned long long int time)
: _fn(fn),
_intendedTime(time)
{
}
bool operator()(unsigned long long int time)
{
return _fn(time);
}
};
void main()
{
typedef std::deque<UpdateFunction> UpdateQueue;
UpdateQueue _updateQueue;
_updateQueue.push_back(UpdateFunction(outsideFunction, 10));
}
I have never seen any code where someone derives from std::function so I'm not even sure this would work as expected.
An answer which comes close to what I'm trying to do is this: https://stackoverflow.com/a/9050114/4076418, but I don't need variable arguments (actually, I have only one single signature, which is in the code above), so I thought it might be better to just derive from std::function instead of contain an instance of it. To be honest, I have no idea how slow or fast std::function is; I've read mentions of type erasure but I'm still trying to figure out what that is.
NB: I am a C++ beginner and I'm trying to wrap my head around references and move semantics, so I apologize if there are obvious errors in the code, or if the coding style is horrible.

I would go with a variant of option 2. This gives you the flexibility of function but avoids the headache of subclassing and needing to deal with the constructors.
struct UpdateFunction {
std::function<bool(unsigned long long int)> fn;
unsigned long long int _intendedTime;
};
You don't even need a special constructor, you can just say
queue.push_back(UpdateFunction{outsideFunction, 10});

Related

C++ templates reading type from configuration file at runtime

I've been trying to write a piece of code that reads a configuration file at runtime, and this file contains the names of different variables, and their type. These types are almost all builtin (int, unsigned int, char*, unsigned long long, float), with the exception of one class which stores information as binary flags.
Example configuration file contains:
Name std::string Measurement
PositionX float 0.004
PositionY float 0.002
Time unsigned long long 1521479000
Function which needs this information:
std::vector<float> xPos;
...
while( loops_over_a_file_containing_values );
...
xPos.push_back(get_information["PositionX"].extract<float>());
However, I cannot for the life of me seem to find a method in which to define these in a C++ code, most of my googling leads me to "This doesn't work" or answers that are so complicated to me that I cannot implement it in a reasonable way.
The main reason behind this is because there are a rather large number of variables with different types, and their type is needed as this function comes from another user written C++ package (which I have no way to modify in any shape or form).
So far I've looked at boost::any, boost::variant but I can't see how this could be done with those. And I'm unsure how exactly to go about this with templates either, I've tried:
template <int ModeDecider> class TypeDecider{ };
template <> class TypeDecider<0>{ public: typedef int Type; };
template <> class TypeDecider<1>{ public: typedef unsigned int Type; };
template <> class TypeDecider<2>{ public: typedef unsigned long long Type; };
template <> class TypeDecider<3>{ public: typedef float Type; };
...
std::string test1 = "unsigned long long";
std::string test2 = "1521479000";
switch( test1 ){
...
std::vector<TypeDecider<2>::Type> testvec;
testvec.push_back(static_cast<TypeDecider<2>::Type>(test2));
...}
But this gives me:
cannot convert 'std::__cxx11::string' (aka 'basic_string<char>') to 'TypeDecider<2>::Type' (aka 'unsigned long long') without a conversion operator
Which I'm not exactly sure how to go about fixing. And so far my googling-fu has yielded very little. As such, I'm here asking for help before I go to the awful step of writing a Python script in order to write the C++ script.

Another void* topic; I just have to ask because I am confused

Ok, muddling though Stack on the particulars about void*, books like The C Programming Language (K&R) and The C++ Programming Language (Stroustrup). What have I learned? That void* is a generic pointer with no type inferred. It requires a cast to any defined type and printing void* just yields the address.
What else do I know? void* can't be dereferenced and thus far remains the one item in C/C++ from which I have discovered much written about but little understanding imparted.
I understand that it must be cast such as *(char*)void* but what makes no sense to me for a generic pointer is that I must somehow already know what type I need in order to grab a value. I'm a Java programmer; I understand generic types but this is something I struggle with.
So I wrote some code
typedef struct node
{
void* data;
node* link;
}Node;
typedef struct list
{
Node* head;
}List;
Node* add_new(void* data, Node* link);
void show(Node* head);
Node* add_new(void* data, Node* link)
{
Node* newNode = new Node();
newNode->data = data;
newNode->link = link;
return newNode;
}
void show(Node* head)
{
while (head != nullptr)
{
std::cout << head->data;
head = head->link;
}
}
int main()
{
List list;
list.head = nullptr;
list.head = add_new("My Name", list.head);
list.head = add_new("Your Name", list.head);
list.head = add_new("Our Name", list.head);
show(list.head);
fgetc(stdin);
return 0;
}
I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out? This implies I already need to know the type, and this reveals nothing about the generic nature of void* while I follow what is here although still no understanding.
Why am I expecting void* to cooperate and the compiler to automatically cast out the type that is hidden internally in some register on the heap or stack?
I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out?
You can't. You must know the valid types that the pointer can be cast to before you can dereference it.
Here are couple of options for using a generic type:
If you are able to use a C++17 compiler, you may use std::any.
If you are able to use the boost libraries, you may use boost::any.
Unlike Java, you are working with memory pointers in C/C++. There is no encapsulation whatsoever. The void * type means the variable is an address in memory. Anything can be stored there. With a type like int * you tell the compiler what you are referring to. Besides the compiler knows the size of the type (say 4 bytes for int) and the address will be a multiple of 4 in that case (granularity/memory alignment). On top, if you give the compiler the type it will perform consistency checks at compilation time. Not after. This is not happening with void *.
In a nutshell, you are working bare metal. The types are compiler directives and do not hold runtime information. Nor does it track the objects you are dynamically creating. It is merely a segment in memory that is allocated where you can eventually store anything.
The main reason to use void* is that different things may be pointed at. Thus, I may pass in an int* or Node* or anything else. But unless you know either the type or the length, you can't do anything with it.
But if you know the length, you can handle the memory pointed at without knowing the type. Casting it as a char* is used because it is a single byte, so if I have a void* and a number of bytes, I can copy the memory somewhere else, or zero it out.
Additionally, if it is a pointer to a class, but you don't know if it is a parent or inherited class, you may be able to assume one and find out a flag inside the data which tells you which one. But no matter what, when you want to do much beyond passing it to another function, you need to cast it as something. char* is just the easiest single byte value to use.
Your confusion derived from habit to deal with Java programs. Java code is set of instruction for a virtual machine, where function of RAM is given to a sort of database, which stores name, type, size and data of each object. Programming language you're learning now is meant to be compiled into instruction for CPU, with same organization of memory as underlying OS have. Existing model used by C and C++ languages is some abstract built on top of most of popular OSes in way that code would work effectively after being compiled for that platform and OS. Naturally that organization doesn't involve string data about type, except for famous RTTI in C++.
For your case RTTI cannot be used directly, unless you would create a wrapper around your naked pointer, which would store the data.
In fact C++ library contains a vast collection of container class templates that are useable and portable, if they are defined by ISO standard. 3/4 of standard is just description of library often referred as STL. Use of them is preferable over working with naked pointers, unless you mean to create own container for some reason. For particular task only C++17 standard offered std::any class, previously present in boost library. Naturally, it is possible to reimplement it, or, in some cases, to replace by std::variant.
Assuming I have no understanding of the type stored in void*, how do I get the value out
You don't.
What you can do is record the type stored in the void*.
In c, void* is used to pass around a binary chunk of data that points at something through one layer of abstraction, and recieve it at the other end, casting it back to the type that the code knows it will be passed.
void do_callback( void(*pfun)(void*), void* pdata ) {
pfun(pdata);
}
void print_int( void* pint ) {
printf( "%d", *(int*)pint );
}
int main() {
int x = 7;
do_callback( print_int, &x );
}
here, we forget thet ype of &x, pass it through do_callback.
It is later passed to code inside do_callback or elsewhere that knows that the void* is actually an int*. So it casts it back and uses it as an int.
The void* and the consumer void(*)(void*) are coupled. The above code is "provably correct", but the proof does not lie in the type system; instead, it depends on the fact we only use that void* in a context that knows it is an int*.
In C++ you can use void* similarly. But you can also get fancy.
Suppose you want a pointer to anything printable. Something is printable if it can be << to a std::ostream.
struct printable {
void const* ptr = 0;
void(*print_f)(std::ostream&, void const*) = 0;
printable() {}
printable(printable&&)=default;
printable(printable const&)=default;
printable& operator=(printable&&)=default;
printable& operator=(printable const&)=default;
template<class T,std::size_t N>
printable( T(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
T* ptr = (T*)pt;
for (std::size_t i = 0; i < N; ++i)
os << ptr[i];
})
{}
template<std::size_t N>
printable( char(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
os << (char const*)pt;
})
{}
template<class T,
std::enable_if_t<!std::is_same<std::decay_t<T>, printable>{}, int> =0
>
printable( T&& t ):
ptr( std::addressof(t) ),
print_f( []( std::ostream& os, void const* pt) {
os << *(std::remove_reference_t<T>*)pt;
})
{}
friend
std::ostream& operator<<( std::ostream& os, printable self ) {
self.print_f( os, self.ptr );
return os;
}
explicit operator bool()const{ return print_f; }
};
what I just did is a technique called "type erasure" in C++ (vaguely similar to Java type erasure).
void send_to_log( printable p ) {
std::cerr << p;
}
Live example.
Here we created an ad-hoc "virtual" interface to the concept of printing on a type.
The type need not support any actual interface (no binary layout requirements), it just has to support a certain syntax.
We create our own virtual dispatch table system for an arbitrary type.
This is used in the C++ standard library. In c++11 there is std::function<Signature>, and in c++17 there is std::any.
std::any is void* that knows how to destroy and copy its contents, and if you know the type you can cast it back to the original type. You can also query it and ask it if it a specific type.
Mixing std::any with the above type-erasure techinque lets you create regular types (that behave like values, not references) with arbitrary duck-typed interfaces.

Why does initialization of int by parenthesis inside class give error? [duplicate]

For example, I cannot write this:
class A
{
vector<int> v(12, 1);
};
I can only write this:
class A
{
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
};
Why is there a difference between these two declaration syntaxes?
The rationale behind this choice is explicitly mentioned in the related proposal for non static data member initializers :
An issue raised in Kona regarding scope of identifiers:
During discussion in the Core Working Group at the September ’07 meeting in Kona, a question arose about the scope of identifiers in the initializer. Do we want to allow class scope with the possibility of forward lookup; or do we want to require that the initializers be well-defined at the point that they’re parsed?
What’s desired:
The motivation for class-scope lookup is that we’d like to be able to put anything in a non-static data member’s initializer that we could put in a mem-initializer without significantly changing the semantics (modulo direct initialization vs. copy initialization):
int x();
struct S {
int i;
S() : i(x()) {} // currently well-formed, uses S::x()
// ...
static int x();
};
struct T {
int i = x(); // should use T::x(), ::x() would be a surprise
// ...
static int x();
};
Problem 1:
Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed:
struct S {
int i(x); // data member with initializer
// ...
static int x;
};
struct T {
int i(x); // member function declaration
// ...
typedef int x;
};
One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it’s a function:
struct S {
int i(j); // ill-formed...parsed as a member function,
// type j looked up but not found
// ...
static int j;
};
A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it’s something else; and we can use “typename” if we really mean a type:
struct S {
int i(x); // unabmiguously a data member
int j(typename y); // unabmiguously a member function
};
Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “int i();” at block scope doesn’t declare a default-initialized int).
The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases, for example:
HashingFunction hash_algorithm{"MD5"};
Here, we could not use the = form because HasningFunction’s constructor is explicit.
In especially tricky cases, a type might have to be mentioned twice. Consider:
vector<int> x = 3; // error: the constructor taking an int is explicit
vector<int> x(3); // three elements default-initialized
vector<int> x{3}; // one element with the value 3
In that case, we have to chose between the two alternatives by using the appropriate notation:
vector<int> x = vector<int>(3); // rather than vector<int> x(3);
vector<int> x{3}; // one element with the value 3
Problem 2:
Another issue is that, because we propose no change to the rules for initializing static data members, adding the static keyword could make a well-formed initializer ill-formed:
struct S {
const int i = f(); // well-formed with forward lookup
static const int j = f(); // always ill-formed for statics
// ...
constexpr static int f() { return 0; }
};
Problem 3:
A third issue is that class-scope lookup could turn a compile-time error into a run-time error:
struct S {
int i = j; // ill-formed without forward lookup, undefined behavior with
int j = 3;
};
(Unless caught by the compiler, i might be intialized with the undefined value of j.)
The proposal:
CWG had a 6-to-3 straw poll in Kona in favor of class-scope lookup; and that is what this paper proposes, with initializers for non-static data members limited to the “= initializer-clause” and “{ initializer-list }” forms.
We believe:
Problem 1: This problem does not occur as we don’t propose the () notation. The = and {} initializer notations do not suffer from this problem.
Problem 2: adding the static keyword makes a number of differences, this being the least of them.
Problem 3: this is not a new problem, but is the same order-of-initialization problem that already exists with constructor initializers.
One possible reason is that allowing parentheses would lead us back to the most vexing parse in no time. Consider the two types below:
struct foo {};
struct bar
{
bar(foo const&) {}
};
Now, you have a data member of type bar that you want to initialize, so you define it as
struct A
{
bar B(foo());
};
But what you've done above is declare a function named B that returns a bar object by value, and takes a single argument that's a function having the signature foo() (returns a foo and doesn't take any arguments).
Judging by the number and frequency of questions asked on StackOverflow that deal with this issue, this is something most C++ programmers find surprising and unintuitive. Adding the new brace-or-equal-initializer syntax was a chance to avoid this ambiguity and start with a clean slate, which is likely the reason the C++ committee chose to do so.
bar B{foo{}};
bar B = foo();
Both lines above declare an object named B of type bar, as expected.
Aside from the guesswork above, I'd like to point out that you're doing two vastly different things in your example above.
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
The first line initializes v1 to a vector that contains two elements, 12 and 1. The second creates a vector v2 that contains 12 elements, each initialized to 1.
Be careful of this rule - if a type defines a constructor that takes an initializer_list<T>, then that constructor is always considered first when the initializer for the type is a braced-init-list. The other constructors will be considered only if the one taking the initializer_list is not viable.

casting void* to std::function

I have an issue. I'm trying to convert a void* to std::function.
This is just a simple example, any suggestions will be appreciated
#.h file
class Example {
public:
Example();
int foo(void* hi);
int fooFunc(std::function<int(int, int)> const& arg, int x, int y) {
foo(arg.target<void*>(), x, y);
return 2;
}
};
#.cpp file
Example::Example() {
}
int Example::foo(void * func, int x, int y)
{
//cast back to std::function
func(x, y);
std::cout << "running in foo: " << a << "\n";
return a;
}
Every casting i tried did not work.
I know i can send a std::function in this example, but it's for something bigger and i'm working on an example to make it work here.
The whole meaning of void*, is for sometimes to use it, in these situations, when you don't know what you will receive, and then cast it to the specific usage you need.
Thanks!
You can't.
You can cast a data pointer to void* and then back to the same pointer type you have started with. std::function is not a pointer type, so the cast is statically invalid, and it's not the same thing you have started with. You have started with a .target of type void(*)() but it's not a data pointer, it's a function pointer, so casting it to void* and back is implementation-defined.
You can:
Ignore the issue and cast to void(*)() anyway. Will work on most (but not all) platforms.
Use void(*)() instead of void* as a universal function pointer (you can cast it to other function types).
Use whatever tools C++ offers to avoid the cast altogether.

Construct a 'long long'

How do you construct a long long in gcc, similar to constructing an int via int()
The following fails in gcc (4.6.3 20120306) (but passes on MSVC for example).
myFunctionCall(someValue, long long());
with error expected primary-expression before 'long' (the column position indicates the first long is the location).
A simple change
myFunctionCall(someValue, (long long)int());
works fine - that is construct an int and cast to long long - indicating that gcc doesn't like the long long ctor.
Summary Solution
To summarize the brilliant explanation below from #birryree:
many compilers don't support long long() and it may not be standards compliant
constructing long long is equivalent to the literal 0LL, so use myFunctionCall(someValue, 0LL)
alternatively use a typedef long_long_t long long then long_long_t()
lastly, consider using uint64_t if you are after a type that is exactly 64 bits on any platform, rather than a type that is at least 64 bits, but may vary on different platforms.
I wanted a definitive answer on what the expected behavior was, so I posted a question on comp.lang.c++.moderated and got some great answers in return. So a thank you goes out to Johannes Schaub, Alf P. Steinbach (both from SO), and Francis Glassborrow for some information
This is not a bug in GCC - in fact it will break across multiple compilers - GCC 4.6, GCC 4.7, and Clang complain about similar errors like primary expression expected before '(' if you try this syntax:
long long x = long long();
Some primitives have spaces, and that is not allowed if you want to use the constructor-style initialization because of binding (long() is bound, but long long() has a free long). Types with spaces in them (like long long) can not use the type()-construction form.
MSVC is more permissive here, though technically non-standard compliant (and it's not a language extension that you can disable).
Solutions/Workarounds
There are alternatives for what you want to do:
Use 0LL as your value in place of attempting long long() - they would produce the same value.
This is how most code will be written too, so it will be most understandable to anyone else reading your code.
From your comments it seems like you really want long long, so you can typedef yourself to always guarantee you have a long long type, like this:
int main() {
typedef long long MyLongLong;
long long x = MyLongLong(); // or MyLongLong x = MyLongLong();
}
Use a template to get around needing explicit naming:
template<typename TypeT>
struct Type { typedef TypeT T(); };
// call it like this:
long long ll = Type<long long>::T();
As I mentioned in my comments, you can use an aliased type, like int64_t (from <cstdint>), which across common platforms is a typedef long long int64_t. This is a more platform dependent than the previous items in this list.
int64_t is a fixed-width type that is 64-bits, which is typically how wide long long is on platforms like linux-x86 and windows-x86. long long is at least 64-bit wide, but can be longer. If your code will only run on certain platforms, or if you really need a fixed-width type, this might be a viable choice.
C++11 Solutions
Thanks to the C++ newsgroup, I learned some additional ways of doing what you want to do, but unfortunately they're only in the realm of C++11 (and MSVC10 doesn't support either, and only very new compilers either way would):
The {} way:
long long ll{}; // does the zero initialization
Using what Johannes refers to as the 'bord tools' in C++11 with std::common_type<T>
#include <type_traits>
int main() {
long long ll = std::common_type<long long>::type();
}
So is there a real difference between () and initializing with 0 for POD types?
You say this in a comment:
I don't think default ctor returns zero always - more typical behaviour is to leave memory untouched.
Well, for primitive types, that is not true at all.
From Section 8.5 of the ISO C++ Standard/2003 (don't have 2011, sorry, but this information didn't change too much):
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default
constructor);
— if T is an array type, each element is
default-initialized;
— otherwise, the object is zero-initialized.
The last clause is most important here because long long, unsigned long, int, float, etc. are all scalar/POD types, and so calling things like this:
int x = int();
Is exactly the same as doing this:
int x = 0;
Generated code example
Here is a more concrete example of what actually happens in code:
#include <iostream>
template<typename T>
void create_and_print() {
T y = T();
std::cout << y << std::endl;
}
int main() {
create_and_print<unsigned long long>();
typedef long long mll;
long long y = mll();
long long z = 0LL;
int mi = int();
}
Compile this with:
g++ -fdump-tree-original construction.cxx
And I get this in the generated tree dump:
;; Function int main() (null)
;; enabled by -tree-original
{
typedef mll mll;
long long int y = 0;
long long int z = 0;
int mi = 0;
<<cleanup_point <<< Unknown tree: expr_stmt
create_and_print<long long unsigned int> () >>>>>;
<<cleanup_point long long int y = 0;>>;
<<cleanup_point long long int z = 0;>>;
<<cleanup_point int mi = 0;>>;
}
return <retval> = 0;
;; Function void create_and_print() [with T = long long unsigned int] (null)
;; enabled by -tree-original
{
long long unsigned int y = 0;
<<cleanup_point long long unsigned int y = 0;>>;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) std::basic_ostream<char>::operator<< ((struct __ostream_type *) std::basic_ostream<char>::operator<< (&cout, y), endl) >>>>>;
}
Generated Code Implications
So from the code tree generated above, notice that all my variables are just being initialized with 0, even if I use constructor-style default initialization, like with int mi = int(). GCC will generate code that just does int mi = 0.
My template function that just attempts to do default construction of some passed in typename T, where T = unsigned long long, also produced just a 0-initialization code.
Conclusion
So in conclusion, if you want to default construct primitive types/PODs, it's like using 0.

Resources