When is useful to use std::any? [duplicate] - c++

Since C++17 std::any is introduced. One can now write code like this
#include <iostream>
#include <any>
#include <string>
int main () {
const double d = 1.2;
std::any var = d;
const std::string str = "Hello World";
var = str;
}
A double is assigned to the variable var and than a std::string was assigned to it.
Why has std::any been introduced?
I think this is violating the least astonishment rule, because I find it hard to think of a situation, where this can be used to express more clearly, what I like to express.
Can somebody give me a good example, when std::any is beneficial.
https://gcc.godbolt.org/z/-kepOD

When to Use
void* as an extremely unsafe pattern with some limited use cases, std::any adds type-safety, and that’s why it has some real use cases.
Some possibilities:
In Libraries - when a library type has to hold or pass anything without knowing the
set of available types.
Parsing files - if you really cannot specify what are the supported
types.
Message passing.
Bindings with a scripting language.
Implementing an interpreter for a scripting language
User Interface - controls might hold anything
Entities in an editor
(ref)

I would summarize it as classic "use when you cannot avoid it".
I can only think of non-performance-critical implementations of dynamically typed scripting languages to represent variables from the scripting world, but even that with a stretch (Boost.Spirit/example/qi/compiler_tutorial does it without, for both the parser and the runtime).
For everything else from parsers (e.g. Boost.Spirit.X3) to library APIs (e.g. ASIO) there would usually be a faster/better/more-specific alternative, as very few things are really "anything", most are more specific than that.
std::variant and/or std::optional for "almost any value"
std::packaged_task / std::function + lambdas for "callback with arguments", which would be a case of void* in C APIs.
etc.
Specifically, I wouldn't blindly plug it as a replacement for a void*, as it may allocate memory on the heap, which can be deadly for high performance code.

std::any is a vocabulary type. When you need to store, well, some bit of anything, as a value you can use it.
There are a number of "first level" uses of it:
When interacting with scripting languages which themselves have such types, it is a natural fit.
When you have a property tree with highly polymorphic content, and the structure of the tree is decoupled from the producer and consumer of the tree.
When replacing the equivalent of a void* chunk of data being passed through an intermediate layer who really doesn't care what it is carrying.
It can also be used as a building block in other cases. For example, std::function could choose to store its value in the std::any:
template<class R, class...Args>
struct func<R(Args...)> {
mutable std::any state;
R(*f)(std::any& state, Args&&...) = nullptr;
template<class T>
void bind(T&& t) {
state = std::forward<T>(t);
f = [](std::any& state, Args&&...args)->R {
return std::any_cast<T&>(state)(std::forward<Args>(args)...);
};
}
R operator()(Args...args)const {
return f(state, std::forward<Args>(args)...);
}
};
that is a pretty small implementation of (most of) std::function. Basically I've used any to type erase copy/move/destroy.
You can using this elsewhere for similar problems (where you are type-erasing some operation and also want to type erase copy/move/destroy), or generalize it.

It's used in Wt, to provide a non-template interface for tabular data.
There are conversions to string for builtin and Wt types, and you can register additional conversions by specialising Wt::any_traits. This allows anything to be displayed as an entry in a table, the view classes don't have to know anything about the types they are displaying.

Related

how to declare variable using typeinfo.name C++

I love coding, and generally do so in Python due to its simplicity and power.
However, for some time critical programs/tasks, I use C++.
Therefore, to get best of both worlds, I am making a Pythonesque list in C++.
AIM: I would like to be able to add any variable or value of any data type, including classes user has defined.
To do this, I have a structure item with a char * value, a char * type and an int size.
My List has an array of these item * s.
Now, I have taken the variable in a template function:
template<class T> item * encode(const T& var);
and declared a pointer to item item * i = new item;
And, I have stored the values of these variables as c style strings.
For example, 14675 in binary is 0000 0000 0000 0000 0011 1001 0101 0011
Therefore, I have dynamically created space, like so:
i->size = sizeof(var);
i->value = new char[i->size]; //4 in this case
and set each bit in value with respective bits in var.
I have also stored their types as
i->type = typeinfo(var).name();
So far so good!
Now, I am stuck with auto decode(item * i) -> decltype(/*What goes here???*/)
How do I specify the return type of the function?
Is there any possible way?
Preferably using the i->type?
Or, should I make changes in the basic design of this process?
Thanks in advance!
Answering your question
I would like to be able to add any variable or value of any data type, including classes user has defined.
Without cooperation from the user that’s impossible in C++.
Remember that C++ types are a compile-time concept only. They do not exist at runtime. The only type information available at runtime is the thin layer of RTTI provided by typeid(). Runtime duck-typing like in Python is not possible.
You can create a container of arbitrary objects quite easily.
std::vector<std::any> v; // requires C++17
However the user of that container has to know what index contains what type:
if (v[0].type() == typeid(ArbitraryUserType)) {
const auto& item = std::any_cast<ArbitraryUserType>(v[0]);
// work on item ...
}
Because of the compile-time nature of types you as the library writer cannot perform that any_cast. It has to be spelled out in the user’s source code.
In general, don’t try to shoehorn a pythonic mindset into C++. It never ends well, especially when you try to circumvent one of the most basic foundations of C++: its powerful static type system.
Notes:
Without C++17 you could use boost::any.
If you know the list of possible types at compile-time std::vector<std::variant<Type1, Type2, etc>> is a good alternative. With any the user is fully responsible to keep track of their types. Because all type checks happen at runtime the compiler cannot help. Variant on the other hand brings back a large chunk of the compile-time safety. And again there’s boost::variant as a non-C++17 alternative.
Notes on your encoding approach
Basically you’re trying to serialize (encode) and deserialize (decode) arbitrary types. Without cooperation from those types, that’s not possible.
Your approach only works for trivial types that can be copied bit by bit. C++ even has a type trait for that: std::is_trivially_copyable. In the end you support fundamental types and C-style structs of those, but nothing else.
Imagine the T for your encode() function was std::string. Simply put a std::string contains a pointer to a separately allocated piece of memory where the actual string data is stored. The string object itself is just a managing wrapper for that pointer. encode() only serializes the wrapper object, but not the pointed-to memory block with the actual data.
Even if during deserialization you could instantiate arbitrary types from a stream of bits, the stream is not complete. What you’d have to implement is a C++ version of Python’s copy.deepcopy, which is impossible without cooperation from each type. Have a look at a C++ serialization library – take Cereal as a straight-forward example – to see how that cooperation can look in practice.

Void pointer in C++

I learned that templates are the void* equivalents in C++. Is this true?
I have this issue in polling "events" off some procedure, when I have an EventType variable and I may also need to pass raw data that is related to that event.
struct WindowEvent {
enum Type {WINDOW_SIZE_CHANGE, USER_CLICK, ...};
void* data;
};
The user may then cast data to the necessary type, depending on the event type.
Is this approach okay in C++? Are there any better approaches?
In C, which generally lacks support for polymorphism, void* pointers can be used to accept data of any type, along with some run-time representation of the actual type, or just knowledge that the data will be casted back to the correct type.
In C++ and other languages with support for polymorphism one will generally instead use either dynamic polymorphism (classes with virtual functions) or static polymorphism (function overloads and templates).
The main difference is that the C approach yields dynamic (run time) manual type checking, while the C++ approaches yield mostly static (compile time) and fully automated type checking. This means less time spent on testing and hunting down silly easily preventable bugs. The cost is more verbose code, and that means that there's a code size offset somewhere, under which the C approach probably rules for productivity, and above which the C++ approaches rule.
"I learned that templates are the void equivalents in C++. Is this true?"*
No - Templates maintain type safety
"Is this approach okay in C++?"
No
"Are there any better approaches?"
Depending on the use case one could use (for example)
class EventData {
public:
virtual int getData() = 0;
};
And then use the appropriate inherited class. Perhaps using smart pointers.

What is the purpose of boost::fusion?

Ive spent the day reading notes and watching a video on boost::fusion and I really don't get some aspects to it.
Take for example, the boost::fusion::has_key<S> function. What is the purpose of having this in boost::fusion? Is the idea that we just try and move as much programming as possible to happen at compile-time? So pretty much any boost::fusion function is the same as the run-time version, except it now evaluates at compile time? (and we assume doing more at compile-time is good?).
Related to boost::fusion, i'm also a bit confused why metafunctions always return types. Why is this?
Another way to look at boost::fusion is to think of it as "poor man introspection" library. The original motivation for boost::fusion comes from the direction of boost::spirit parser/generator framework, in particular the need to support what is called "parser attributes".
Imagine, you've got a CSV string to parse:
aaaa, 1.1
The type, this string parses into, can be described as "tuple of string and double". We can define such tuples in "plain" C++, either with old school structs (struct { string a; double b; } or newer tuple<string, double>). The only thing we miss is some sort of adapter, which will allow to pass tuples (and some other types) of arbitrary composition to a unified parser interface and expect it to make sense of it without passing any out of band information (such as string parsing templates used by scanf).
That's where boost::fusion comes into play. The most straightforward way to construct a "fusion sequence" is to adapt a normal struct:
struct a {
string s;
double d;
};
BOOST_FUSION_ADAPT_STRUCT(a, (string, s)(double, d))
The "ADAPT_STRUCT" macro adds the necessary information for parser framework (in this example) to be able to "iterate" over members of struct a to the tune of the following questions:
I just parsed a string. Can I assign it to first member of struct a?
I just parsed a double. Can I assign it to second member of struct a?
Are there any other members in struct a or should I stop parsing?
Obviously, this basic example can be further extended (and boost::fusion supplies the capability) to address much more complex cases:
Variants - let's say parser can encounter either sting or double and wants to assign it to the right member of struct a. BOOST_FUSION_ADAPT_ASSOC_STRUCT comes to the rescue (now our parser can ask questions like "which member of struct a is of type double?").
Transformations - our parser can be designed to accept certain types as parameters but the rest of the programs had changed quite a bit. Yet, fusion metafunctions can be conveniently used to adapt new types to old realities (or vice versa).
The rest of boost::fusion functionality naturally follows from the above basics. fusion really shines when there's a need for conversion (in either direction) of "loose IO data" to strongly typed/structured data C++ programs operate upon (if efficiency is of concern). It is the enabling factor behind spirit::qi and spirit::karma being such an efficient (probably the fastest) I/O frameworks .
Fusion is there as a bridge between compile-time and run-time containers and algorithms. You may or may not want to move some of your processing to compile-time, but if you do want to then Fusion might help. I don't think it has a specific manifesto to move as much as possible to compile-time, although I may be wrong.
Meta-functions return types because template meta-programming wasn't invented on purpose. It was discovered more-or-less by accident that C++ templates can be used as a compile-time programming language. A meta-function is a mapping from template arguments to instantiations of a template. As of C++03 there were are two kinds of template (class- and function-), therefore a meta-function has to "return" either a class or a function. Classes are more useful than functions, since you can put values etc. in their static data members.
C++11 adds another kind of template (for typedefs), but that is kind of irrelevant to meta-programming. More importantly for compile-time programming, C++11 adds constexpr functions. They're properly designed for the purpose and they return values just like normal functions. Of course, their input is not a type, so they can't be mappings from types to something else in the way that templates can. So in that sense they lack the "meta-" part of meta-programming. They're "just" compile-time evaluation of normal C++ functions, not meta-functions.

What are good use-cases for tuples in C++11?

What are good use-cases for using tuples in C++11? For example, I have a function that defines a local struct as follows:
template<typename T, typename CmpF, typename LessF>
void mwquicksort(T *pT, int nitem, const int M, CmpF cmp, LessF less)
{
struct SI
{
int l, r, w;
SI() {}
SI(int _l, int _r, int _w) : l(_l), r(_r), w(_w) {}
} stack[40];
// etc
I was considering to replace the SI struct with an std::tuple<int,int,int>, which is a far shorter declaration with convenient constructors and operators already predefined, but with the following disadvantages:
Tuple elements are hidden in obscure, implementation-defined structs. Even though Visual studio interprets and shows their contents nicely, I still can't put conditional breakpoints that depend on value of tuple elements.
Accessing individual tuple fields (get<0>(some_tuple)) is far more verbose than accessing struct elements (s.l).
Accessing fields by name is far more informative (and shorter!) than by numeric index.
The last two points are somewhat addressed by the tie function. Given these disadvantages, what would be a good use-case for tuples?
UPDATE Turns out that VS2010 SP1 debugger cannot show the contents of the following array std::tuple<int, int, int> stack[40], but it works fine when it's coded with a struct. So the decision is basically a no-brainer: if you'll ever have to inspect its values, use a struct [esp. important with debuggers like GDB].
It is an easy way to return multiple values from a function;
std::tuple<int,int> fun();
The result values can be used elegantly as follows:
int a;
int b;
std::tie(a,b)=fun();
Well, imho, the most important part is generic code. Writing generic code that works on all kinds of structs is a lot harder than writing generics that work on tuples. For example, the std::tie function you mentioned yourself would be very nearly impossible to make for structs.
this allows you to do things like this:
Store function parameters for delayed execution (e.g. this question )
Return multiple parameters without cumbersome (un)packing with std::tie
Combine (not equal-typed) data sets (e.g. from parallel execution), it can be done as simply as std::tuple_cat.
The thing is, it does not stop with these uses, people can expand on this list and write generic functionality based on tuples that is much harder to do with structs. Who knows, maybe tomorrow someone finds a brilliant use for serialization purposes.
I think most use for tuples comes from std::tie:
bool MyStruct::operator<(MyStruct const &o) const
{
return std::tie(a, b, c) < std::tie(o.a, o.b, o.c);
}
Along with many other examples in the answers here. I find this example to be the most commonly useful, however, as it saves a lot of effort from how it used to be in C++03.
I think there is NO good use for tuples outside of implementation details of some generic library feature.
The (possible) saving in typing do not offset the losses in self-documenting properties of the resulting code.
Substituting tuples for structs that just takes away a meaningful name for a field, replacing the field name with a "number" (just like the ill-conceived concept of an std::pair).
Returning multiple values using tuples is much less self-documenting then the alternatives -- returning named types or using named references. Without this self-documenting, it is easy to confuse the order of the returned values, if they are mutually convertible.
Have you ever used std::pair? Many of the places you'd use std::tuple are similar, but not restricted to exactly two values.
The disadvantages you list for tuples also apply to std::pair, sometimes you want a more expressive type with better names for its members than first and second, but sometimes you don't need that. The same applies to tuples.
The real use cases are situations where you have unnameable elements- variadic templates and lambda functions. In both situations you can have unnamed elements with unknown types and thus the only way to store them is a struct with unnamed elements: std::tuple. In every other situation you have a known # of name-able elements with known types and can thus use an ordinary struct, which is the superior answer 99% of the time.
For example, you should NOT use std::tuple to have "multiple returns" from ordinary functions or templates w/ a fixed number of generic inputs. Use a real structure for that. A real object is FAR more "generic" than the std::tuple cookie-cutter, because you can give a real object literally any interface. It will also give you much more type safety and flexibility in public libraries.
Just compare these 2 class member functions:
std::tuple<double, double, double> GetLocation() const; // x, y, z
GeoCoordinate GetLocation() const;
With a real 'geo coordinate' object I can provide an operator bool() that returns false if the parent object had no location. Via its APIs users could get the x,y,z locations. But here's the big thing- if I decide to make GeoCoordinate 4D by adding a time field in 6 months, current users's code won't break. I cannot do that with the std::tuple version.
Interoperation with other programming languages that use tuples, and returning multiple values without having the caller have to understand any extra types. Those are the first two that come to my mind.
I cannot comment on mirk's answer, so I'll have to give a separate answer:
I think tuples were added to the standard also to allow for functional style programming. As an example, while code like
void my_func(const MyClass& input, MyClass& output1, MyClass& output2, MyClass& output3)
{
// whatever
}
is ubiquitous in traditional C++, because it is the only way to have multiple objects returned by a function, this is an abomination for functional programming. Now you may write
tuple<MyClass, MyClass, MyClass> my_func(const MyClass& input)
{
// whatever
return tuple<MyClass, MyClass, MyClass>(output1, output2, output3);
}
Thus having the chance to avoid side effects and mutability, to allow for pipelining, and, at the same time, to preserve the semantic strength of your function.
F.21: To return multiple "out" values, prefer returning a struct or tuple.
Prefer using a named struct where there are semantics to the returned value. Otherwise, a nameless tuple is useful in generic code.
For instance, if returned values are value from the input stream and the error code, these values will not ego far together. They are not related enough to justify a dedicated structure to hold both. Differently, x and y pair would rather have a structure like Point.
The source I reference is maintained by Bjarne Stroustrup, Herb Sutter so I think somewhat trustworthy.

C++ equivalent of C# 4.0's "dynamic" keyword?

In C# 4.0, you can use the "dynamic" keyword as a placeholder for a type that is not known until runtime. There are certain corner cases where this is extremely useful behavior. Is it possible to emulate anything like this in C++, possibly using C++0x features or RTTI?
Not really. The closest you can get is a void *, but you still need to cast it to an appropriate type before you can use it.
Update:
Trying to build a duck-typed DSL that compiles to C++, basically.
You can go about this in at least two ways:
Union-based variant
struct MyType {
enum { NUMBER, STRING /* etc */ } type;
union {
double number;
string str;
};
};
Polymorphic class heirarchy
class MyType {
public:
/* define pure virtual operations common to all types */
};
class MyNumber : public MyType {
private:
double number;
public:
/* implement operations for this type */
};
C#'s dynamic feature is highly dependant on .NET's built-in reflection capabilities. As standard C++ offers next to no reflection support, there's no way you can get a similar behavior. RTTI will allow you to safely downcast pointers but that's pretty much it. You're still quite far to being able to enumerate fields and methods and invoke them dynamically.
As others already said this isn't possible in the general case but I think it would be informative to see why not.
There are two levels to the problem, the syntactic level and the semantic level.
On the syntactic level you have the following code:
dynamic d = /* something */;
d.Foo(bar); // Foo is unknown at compile time
In .NET dynamic is a compiler feature, what it does is instead of generating a function call it creates a call site which contains the function name and types of parameters (for overloading). This means that if you want to support dynamic you have to modify the compiler. It's true that template meta programming allows doing similar stuff but TMP is by its nature done at compile time and therefore won't be up to the job of supporting runtime invocation.
If you're not anal about the syntax then you may be able to support something like this:
dynamic d = /* something */;
d.invoke("Foo", bar);
On the semantic level
As #Trillian (cool user name BTW) said, dynamic relies on reflection, this isn't strictly true, you can specify how dynamic is implemented, and the default for CLR types is reflection, so the type that bound to a dynamic variable must support some sort of runtime inspection (e.g. COM's IDispatch). This isn't true for the general case in C++ but if you can narrow your support only to types that support (a known) type of inspection you can implement dynamic in C++ (sans the syntax as mentioned above).
It's not possible. Object sizes need to be known at compile-time, so the stack pointer can move by the appropriate number of bytes. If you don't declare the type, then the compiler won't know the size. C# gets around this problem by making all objects pointers.
This example on github provides one possible implementation, depending on your function complexity.
template <typename X, typename Y>
auto add(X x, Y y) -> decltype(x + y) {
return x + y;
}
add(1, 2); // == 3
add(1, 2.0); // == 3.0
add(1.5, 1.5); // == 3.0
I can't think of a possible code path where the type of a value is actually unknown all the way until run-time. Even if you are linking two modules together (dynamically, at run time), both are already compiled, and the types that they can return are also fully determined, and in fact encoded into the mangled names of the symbols the library exposes.
You can, however, defer knowledge of types until the code must actually be compiled. In C++0x, there's the auto keyword, which provides type inference from the expression used to initialize the variable, and in current C++, you can use templates, like so:
template<typename T>
T square(const T& someArg){
return T*T;
}
Edit: based on your comment on your question, You probably don't have a situation where the type is unknown. What's more likely is that the type is limited to one of a few (predefined) types. for that, you can use a union type, preferably using boost::variant