Skip to content

Commit 466e1cd

Browse files
author
XuhuaHuang
committed
Add notes on std::any and reference wrapper
1 parent deeffcc commit 466e1cd

8 files changed

Lines changed: 176 additions & 17 deletions

File tree

Miscellaneous/CMakeLists.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ cmake_minimum_required(VERSION 3.20)
22

33
project("misc" LANGUAGES CXX)
44

5-
set(CMAKE_CXX_STANDARD 11)
5+
set(CMAKE_CXX_STANDARD 23)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77

8-
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
8+
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
99
# Compiler is Microsoft Visual C++
1010
# Set MSVC-specific flags
1111
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /Zc:__cplusplus /EHsc /std:c++latest /experimental:module")
12+
13+
add_executable(winapi_cmdarg "winapi_cmdarg.cpp")
14+
add_executable(multiple_of "is_multiple_of.cpp")
1215
endif()
1316

14-
add_executable(multiple_of "is_multiple_of.cpp")
1517
add_executable(unions_align "unions_align.cpp")
16-
add_executable(winapi_cmdarg "winapi_cmdarg.cpp")
18+
add_executable(std_any "use_std_any.cpp")
19+
add_executable(std_make_any "use_std_make_any.cpp")

Miscellaneous/use_format.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@
88

99
template <typename... Args>
1010
std::string dyna_print(std::string_view rt_fmt_str, Args&&... args) {
11-
return std::vformat(rt_fmt_str, std::make_format_args(args...));
11+
return std::vformat(rt_fmt_str, std::make_format_args(args...));
1212
}
1313

1414
int main() {
15-
std::cout << std::format("Hello {}!\n", "world");
15+
std::cout << std::format("Hello {}!\n", "world");
1616

17-
std::string fmt;
18-
for (int i{}; i != 3; ++i) {
19-
fmt += "{} "; // constructs the formatting string
20-
std::cout << fmt << " : ";
21-
std::cout << dyna_print(fmt, "alpha", 'Z', 3.14, "unused");
22-
std::cout << '\n';
23-
}
17+
std::string fmt;
18+
for (int i{}; i != 3; ++i) {
19+
fmt += "{} "; // constructs the formatting string
20+
std::cout << fmt << " : ";
21+
std::cout << dyna_print(fmt, "alpha", 'Z', 3.14, "unused");
22+
std::cout << '\n';
23+
}
2424

25-
return 0;
25+
return 0;
2626
}

Miscellaneous/use_std_any.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @file use_std_any.cpp
3+
* @author Xuhua Huang
4+
* @brief
5+
* @version 0.1
6+
* @date 2026-01-18
7+
*
8+
* @copyright Copyright (c) 2026
9+
*
10+
*/
11+
12+
#include <any>
13+
#include <iostream>
14+
15+
int main() {
16+
std::cout << std::boolalpha;
17+
18+
// any type
19+
std::any a = 1;
20+
std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
21+
a = 3.14;
22+
std::cout << a.type().name() << ": " << std::any_cast<double>(a) << '\n';
23+
a = true;
24+
std::cout << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';
25+
26+
// bad cast
27+
try {
28+
a = 1;
29+
std::cout << std::any_cast<float>(a) << '\n';
30+
} catch (const std::bad_any_cast& e) {
31+
std::cout << e.what() << '\n';
32+
}
33+
34+
// has value
35+
a = 2;
36+
if (a.has_value())
37+
std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
38+
39+
// reset
40+
a.reset();
41+
if (!a.has_value())
42+
std::cout << "no value\n";
43+
44+
// pointer to contained data
45+
a = 3;
46+
int* i = std::any_cast<int>(&a);
47+
std::cout << *i << '\n';
48+
49+
return 0;
50+
}

Miscellaneous/use_std_make_any.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file use_std_make_any.cpp
3+
* @author Xuhua Huang
4+
* @brief
5+
* @version 0.1
6+
* @date 2026-01-18
7+
*
8+
* @copyright Copyright (c) 2026
9+
*
10+
*/
11+
12+
#include <any>
13+
#include <complex>
14+
#include <functional>
15+
#include <iostream>
16+
#include <string>
17+
18+
int main() {
19+
auto a0 = std::make_any<std::string>("Hello, std::any!\n");
20+
auto a1 = std::make_any<std::complex<double>>(0.1, 2.3);
21+
22+
std::cout << std::any_cast<std::string&>(a0);
23+
std::cout << std::any_cast<std::complex<double>&>(a1) << '\n';
24+
25+
using lambda = std::function<void(void)>;
26+
27+
// Put a lambda into std::any. Attempt #1 (failed).
28+
std::any a2 = [] { std::cout << "Lambda #1.\n"; };
29+
std::cout << "a2.type() = \"" << a2.type().name() << "\"\n";
30+
31+
// any_cast casts to <void(void)> but actual type is not
32+
// a std::function..., but ~ main::{lambda()#1}, and it is
33+
// unique for each lambda. So, this throws...
34+
try {
35+
std::any_cast<lambda>(a2)();
36+
} catch (const std::bad_any_cast& ex) {
37+
std::cout << ex.what() << '\n';
38+
}
39+
40+
// Put a lambda into std::any. Attempt #2 (successful).
41+
auto a3 = std::make_any<lambda>([] { std::cout << "Lambda #2.\n"; });
42+
std::cout << "a3.type() = \"" << a3.type().name() << "\"\n";
43+
std::any_cast<lambda>(a3)();
44+
45+
return 0;
46+
}

RawPointer/void_ptr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@
1313
#include <cstdlib>
1414
#include <iostream>
1515

16+
/**
17+
* @brief C++ allows pointers without a specific data type associated with them
18+
* These pointers are referred to as void pointers
19+
* Void pointers are frequently used in C to create generic methods as
20+
* they are not tied to particular data types
21+
*
22+
* @note Void pointers cannot be dereferenced
23+
* They need to be explicitly cast to another pointer type before dereferencing
24+
* Pointer arithmetic are not allowed on void pointers
25+
* Some compilers permit pointer arithmetic with void pointers, however, assuming
26+
* the size of void is 1 and so you are essentially working with a block of byte data
27+
*
28+
*/
1629
int main() {
1730
std::nullptr_t np = nullptr;
1831
void* vp = nullptr;

Reference/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
1111
set(CMAKE_INCLUDE_CURRENT_DIR ON)
1212

1313
# Set any necessary compile flags
14-
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
14+
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
1515
# Compiler is Microsoft Visual C++
1616
# Set MSVC-specific flags
1717
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /Zc:__cplusplus /EHsc /std:c17 /std:c++latest /experimental:module")
1818
endif()
1919

20-
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
20+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
2121
# Compiler is g++
2222
# Set g++-specific flags
2323
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
2424
endif()
2525

2626
add_executable(ref "ref.cpp")
27+
add_executable(ref_wrapper "ref_wrapper.cpp")

Reference/ref_wrapper.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file ref_wrapper.cpp
3+
* @author Xuhua Huang
4+
* @brief
5+
* @version 0.1
6+
* @date 2026-01-18
7+
*
8+
* @copyright Copyright (c) 2026
9+
*
10+
*/
11+
12+
#include <concepts>
13+
#include <functional>
14+
#include <iostream>
15+
#include <list>
16+
#include <numeric>
17+
#include <random>
18+
#include <ranges>
19+
#include <vector>
20+
21+
void println(const auto rem, const std::ranges::range auto& v) {
22+
for (std::cout << rem; const auto& e : v)
23+
std::cout << e << ' ';
24+
std::cout << '\n';
25+
}
26+
27+
int main() {
28+
std::list<int> l(10);
29+
std::iota(l.begin(), l.end(), -4);
30+
31+
// can't use shuffle on a list (requires random access), but can use it on a vector
32+
std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
33+
34+
// std::ranges::shuffle(v, std::mt19937{std::random_device{}()});
35+
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});
36+
println("Contents of the list: ", l);
37+
println("Contents of the list, as seen through a shuffled vector: ", v);
38+
39+
std::cout << "Doubling the values in the initial list...\n";
40+
// std::ranges::for_each(l, [](int& i) { i *= 2; });
41+
std::for_each(l.begin(), l.end(), [](int& i) -> void { i *= 2; });
42+
43+
println("Contents of the list, as seen through a shuffled vector: ", v);
44+
45+
return 0;
46+
}

View/views_notes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ std::vector<int> generate_values(int start, int end) {
2424
}
2525

2626
[[nodiscard]] [[gnu::always_inline]]
27-
auto get_data() -> std::vector<int> {
27+
inline auto get_data() -> std::vector<int> {
2828
return generate_values(2, 13);
2929
}
3030

0 commit comments

Comments
 (0)