Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can you switch over a std::any.type()?

Tags:

c++

c++17

any

I want to explore how I can use std::any instead of void * or such constructs for message passing. So I created an example code to test this - see below.

The use of std::any looks nice, but I want to switch through the types to check which type the std::any is. It might no be possible, and I know I can use a if/elseif... block instead, but it would be very nice if I can create a switch statement so that if I use this in real code with 10-20 different types it will be more readable.

#include <string>  
#include <iostream>  
#include <sstream>  
#include <any>  
#include <typeindex>  

struct ints { int a{1}; int b{2}; };
struct strings { std::string a{"string1"}; std::string b{"string2"}; };

void send_msg(std::any item)
{
    switch (item.type().hash_code())       // <------- HERE
    {
        case typeid(ints).hash_code():     // <------- HERE
            std::cout << "ints" << std::endl;
            break;
        case typeid(strings).hash_code():
            std::cout << "strings" << std::endl;
            break;
        default:
            std::cout << "unknown type\n";
    }
}

int main()
{
    strings s;
    send_msg(s);

    ints i;
    send_msg(i);
}

live example: https://godbolt.org/z/xPrMYM

I can't switch on the type_info returned by std::any::type, but I can switch on the hash_code() of the type_info, but that is not a constexpr I hoped it was though!

so I also tried getting the address of the type info and a few other tricks that I could find. But no luck so far...

Is there such a way?

like image 613
code_fodder Avatar asked Dec 14 '20 15:12

code_fodder


People also ask

Can you switch string C++?

Your answerStrings are not supported as a type in C/C++. It does support the concept of a constant char array, but it does not fully comprehend the concept of a string. The compiler must comprehend what it means for two values to be equal in order to create code for a switch statement.

Does std :: Any use RTTI?

Since this function is specific to a given type, you don't need RTTI to perform the operations required by std::any .

Does STD any allocate?

std::any uses Small Buffer Optimization, so it will not dynamically allocate memory for simple types like ints, doubles… but for larger types it will use extra new .

Is std :: Any slow?

Performance of std::any Also, invoking a std::any_cast to retrieve the value is quite slow compared to std::variant . The Boost equivalent of std::any , boost::any , provides a fast version of std::any_cast called boost::any_cast_unsafe which can be utilized if you know which type is contained.

What is std :: any?

The class any describes a type-safe container for single values of any copy constructible type. 1) An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object.


1 Answers

I would also suggest a variant here if possible but for the concrete question:

If you can use boost and C++17 is your referred standard: They provide an extended typeid handling that can also be used for several compile time checks, see

https://www.boost.org/doc/libs/1_67_0/boost/type_index/ctti_type_index.hpp

Its underlying rawType is a const char* constexpr and the typeIndex itself can be used as a perfect replacement for std::type_info. Since the standard guarantees unique addresses for these type identifiers, even a simple address comparison should be possible here (not sure why this simplification is currently out commented inside the boost headers though).

To be usable with any, you might have to wrap it or to use a simple own any type.

like image 153
Secundi Avatar answered Sep 22 '22 14:09

Secundi