This is my first blog about c++17 tutorial std:any example. The class any describes a type-safe container for single values of any type. it can be considered as replacement of void*.

  • we can assign any value to any object , but to read any object we have to proper cast.
#include<iostream>
#include<any>

int main()
{
    auto a = std::any(12);
    a = std::string("Hello Any\n");
   // The non-member any_cast functions provide type-safe access to the contained object.
    std::cout << std::any_cast<std::string>(a) << std::endl;
    return 0;
}
//g++ sample.cc -Wall -Wextra  -std=gnu++17
  • It gives bad any_cast if type mismatch
#include<iostream>
#include<any>

int main()
{
    auto a = std::any(12);
    try 
    {
        std::cout << std::any_cast<std::string>(a) << '\n';
    }
    catch(const std::bad_any_cast& e) 
    {
        std::cout << e.what() << '\n';
    }
    return 0;
}
//$ g++ sample.cc -Wall -Wextra -std=gnu++17 
// output would be bad any_cast
  • The any object has reset modifier which destroys contained object. we can also check if any object has value has_value() is an observer for any object.
#include<iostream>
#include<any>

int main()
{
    auto a = std::any(std::string("wikistack"));
    // reset
    a.reset();
    // check if a has value
    if (!a.has_value())
    {
       std::cout << "a has no value\n";
    }
    return 0;
}
  • The std::any can hold user defined data type provided it should be copy constructible.
#include<iostream>
#include<any>

class foo {
    public:
    foo(int x): a(x) {}
    int a;
};

int main()
{
    std::any v (foo(5));
    std::cout << std::any_cast<foo> (v).a << std::endl;
    return 0;
}

$ g++ sample.cc -Wall -Wextra -std=gnu++17

$./a.out

5

The above example is working even if we have not provided copy constructor  because in this case compiler would generate default copy constructor. Let us delete the default copy constructor and try to compile

#include<iostream>
#include<any>

class foo {
    public:
    foo(int x): a(x) {}
    foo(const foo&)=delete;
    int a;
};

int main()
{
    std::any v (foo(5));
    std::cout << std::any_cast<foo> (v).a << std::endl;
    return 0;
}

$ g++ sample.cc -Wall -Wextra -std=gnu++17

13:23: error: no matching function for call to 'std::any::any(foo)'
     std::any v (foo(5));
                       ^
In file included from prog.cc:2:0:
/opt/wandbox/gcc-7.2.0/include/c++/7.2.0/any:222:7: note: candidate: template<class _ValueType, class _Up, class ... _Args, class _Tp, class _Mgr, typename std::enable_if<std::__and_<std::is_copy_constructible<_Tp>, std::is_constructible<_Tp, std::initializer_list<_Up>, _Args&& ...> >::value, bool>::type <anonymous> > std::any::any(std::in_place_type_t<_Tp>, std::initializer_list<_Up>, _Args&& ...)
       any(in_place_type_t<_ValueType>,
       ^~~

Ref:

http://en.cppreference.com/w/cpp/utility/any



Related Contents to follow