A Better void*
: std::any
¶
Default Initialization¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, default_ctor)
{
std::any a;
ASSERT_EQ(a.type(), typeid(void));
ASSERT_FALSE(a.has_value());
}
Initialization, Assignment, Access¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, basic)
{
std::any a = 42; // <--- int
ASSERT_EQ(a.type(), typeid(int));
int i = std::any_cast<int>(a);
ASSERT_EQ(i, 42);
a = 37.6; // <--- double
ASSERT_EQ(a.type(), typeid(double));
double d = std::any_cast<double>(a);
ASSERT_FLOAT_EQ(d, 37.6);
}
Copy, And Resource Management¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, copy)
{
std::any a1 = std::string("howdy");
std::any a2 = a1; // <--- copy ctor
ASSERT_EQ(std::any_cast<std::string>(a2), "howdy");
std::any a3 = std::vector<int>{1, 2, 3, 4, 5, 6};
a3 = a2; // <--- resource management!
ASSERT_EQ(std::any_cast<std::string>(a3), "howdy");
}
Run-Time Type Errors¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, bad_cast)
{
std::any a = 42;
ASSERT_THROW(
{
std::any_cast<std::string>(a);
},
std::bad_any_cast
);
}
has_value()
: Null?¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, has_value)
{
std::any a = 42;
ASSERT_TRUE(a.has_value());
a.reset();
ASSERT_FALSE(a.has_value());
}
Avoiding Exceptions¶
any_cast<>
on a pointer is different⟶ does not throw
⟶ suitable for
if
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, pointer_cast)
{
std::any a = 42;
ASSERT_NE(std::any_cast<int>(&a), nullptr);
ASSERT_EQ(std::any_cast<const double>(&a), nullptr);
}
Modifying In-Place: std::any_cast<>
To Reference¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, reference_cast)
{
std::any a = 42;
int& i = std::any_cast<int&>(a); // <--- pointer to any-content
i = 666; // <--- modify a
ASSERT_EQ(std::any_cast<int>(a), 666); // <--- a has been modified
}
std::string
And const char*
Are Different¶
#include <gtest/gtest.h>
#include <any>
TEST(any_suite, char_ptr_careful)
{
std::any a = "howdy"; // <-- careful: const char*, not std::string!
ASSERT_EQ(a.type(), typeid(const char*));
const char* s = std::any_cast<const char*>(a);
ASSERT_EQ(s, "howdy"); // <--- this is not obvious!
char* cmp = new char[]{"howdy"};
ASSERT_NE(s, cmp);
delete[] cmp;
}