Daniel Duffy
C++ author, trainer
- Joined
- 10/4/07
- Messages
- 10,469
- Points
- 648
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Great. I just installed it last night.Yes. I am currently completing the course assignments in VS 2019. It's a great product.
// TestSTLVariant101.cpp
//
// Show the essentials of the Variant Library in Boost.
// Supported in C++17, std::variant and std::visit()
//
// Show a variety of methods for type-safe visitation of type-safe unions.
//
// Q. can you get std::variant working with boost::static_visitor<>?
//
// BIG DEAL is: adding functionality NON-INTRUSIVELY to a class by Visior pattern.
//
// (C) Datasim Education BV 2009-2019
//
#include <iostream>
#include <boost/variant.hpp>
#include <variant>
// Basic shapes
struct Point
{
double x;
double y;
void displayPoint()
{
std::cout << "Point: " << x << ", " << y << '\n';
}
};
struct Circle
{
Point centre;
double radius;
void displayCircle()
{
std::cout << "Circle, radius " << radius << '\n';
std::cout << "Centre point "; centre.displayPoint();
}
};
struct LineSegment
{
Point p1;
Point p2;
void displayLineSegment()
{
std::cout << "Line, endpoints "<< '\n';
p1.displayPoint();
p2.displayPoint();
}
};
using VariantBoost = boost::variant<Point, LineSegment, Circle>;
using VariantSTL = std::variant<Point, LineSegment, Circle>;
// Different ways to add functionality/visit shapes
// A. In combination with Boost visitor pattern
class Print_Visitor : public boost::static_visitor<void>
{
public:
void operator () (Point& s) { s.displayPoint(); }
void operator () (LineSegment& s) { s.displayLineSegment(); }
void operator () (Circle& s) { s.displayCircle(); }
};
class Translate_Visitor : public boost::static_visitor<void>
{ // Move the shapes
private:
double off;
public:
Translate_Visitor(double offset) : off(offset) {}
void operator () (Point& s) { s.x += off; s.y += off;}
void operator () (LineSegment& s) {(*this)(s.p1); (*this)(s.p2);}
void operator () (Circle& s) { (*this)(s.centre); }
};
// B. Lambda function to test each type
auto lambdaVisit = [](auto&& arg)
{
using T = std::decay_t < decltype(arg)>;
// Hard-coded switch
if constexpr (std::is_same_v<T, Point>)
arg.displayPoint();
if constexpr (std::is_same_v<T, LineSegment>)
arg.displayLineSegment();
if constexpr (std::is_same_v<T, Circle>)
arg.displayCircle();
};
void MyVisit(VariantSTL& var)
{
std::visit(lambdaVisit, var);
}
void MyVisit2(VariantSTL& v)
{
switch (v.index()) {
case 0:
std::get<0>(v).displayPoint();
break;
case 1:
std::get<1>(v).displayLineSegment();
break;
case 2:
std::get<2>(v).displayCircle();
break;
default:
std::cout << "ugh\n";
}
}
void MyVisit3(VariantSTL& v)
{
switch (v.index()) {
case 0:
std::get<Point>(v).displayPoint();
break;
case 1:
std::get<LineSegment>(v).displayLineSegment();
break;
case 2:
std::get<Circle>(v).displayCircle();
break;
default:
std::cout << "ugh\n";
}
}
int main()
{
// Create some shapes
Point p1{ 1,1 };
Point p2{ 2,1 };
LineSegment myL{ p1, p2 };
double radius = 2.0;
Circle c{ p1, radius };
// Checking the data
std::cout << "\n*** Sanity checks \n";
p1.displayPoint(); p2.displayPoint();
myL.displayLineSegment(); c.displayCircle();
{
// Boost Visitor
std::cout << "\n*** C++11 visit using Boost visitor \n";
VariantBoost var(p1);
Print_Visitor vis;
// Give some values; visit each component
var = p1;
boost::apply_visitor(vis, var);
var = myL;
boost::apply_visitor(vis, var);
var = c;
boost::apply_visitor(vis, var);
}
// C++11 solution
{
std::cout << "\n*** C++11 visit\n";
VariantSTL var(p1);
MyVisit(var);
var = c;
MyVisit(var);
var = myL;
MyVisit(var);
}
// C. Based on the variant's index
{
std::cout << "\n*** C++11 visit using indices \n";
VariantSTL var(p1);
MyVisit2(var);
var = c;
MyVisit2(var);
var = myL;
MyVisit2(var);
}
// D. Based on the variant's type
{
std::cout << "\n*** C++11 visit using type as index \n";
VariantSTL var(p1);
MyVisit3(var);
var = c;
MyVisit3(var);
var = myL;
MyVisit3(var);
}
// E. Translate Visitor
{
std::cout << "\n*** Translate visitor \n";
Point p{ 0.0, 0.0 };
Point p2 {1.0, 1.0 };
LineSegment myL{ p, p2 };
Circle c{ p, 10.0 };
// Boost Visitor
std::cout << "\n*** C++11 visit using Boost visitor \n";
VariantBoost var(p);
double offset = 2.0;
Translate_Visitor vis(offset);
Print_Visitor visP;
// Give some values; visit each component
var = p;
boost::apply_visitor(vis, var);
boost::apply_visitor(visP, var);
var = myL;
boost::apply_visitor(vis, var);
boost::apply_visitor(visP, var);
var = c;
boost::apply_visitor(vis, var);
boost::apply_visitor(visP, var);
/* p.displayPoint();
myL.displayLineSegment();
c.displayCircle();*/
}
return 0;
}
I have just posted some code I ran on VS2019 16.1.1. With /std:c++latestGreat. I just installed it last night.
Installed it on my machine a couple of weeks back. When learning C++ language features, I prefer writing quick code snippets on a site like www.ideone.com. When working with larger data-structures, maybe like creating your own DateTime class or Matrix or SwapLeg, I use Visual Studio.
Definitely better than VS2017
They don't write well-researched books like this any more.
R.G. Dromey How to Solve it by Computer Prentice-Hall 1982
It discusses how to write well-structured modular programs and deep discussions of algorithms and data structures and code in Pascal.
For example, this is a good front-end to C++ STL algorithms and data structures.
Most books (e.g. in Python) are
30% screen sheets
40% tables of output
20% text
10% maths (if you are lucky)
Very little background (e.g. maths, fianance) and certainly no help in developing your own algorithms.
Just using libraries and packages alone means you will always us libraries and packages at the cost of real software design skill IMHO.
BTW I have stopped buying books on Python, for the above reasons.
Caveat: "each to his own"
Thank you. A lot of tine (BTW I have lost count) and effort by myself and better half (tex, etc.)Speaking of which, I've been reading your latest book, and am really enjoying it. Well done. Can't imagine how much time/effort you put into it. Can't thank you enough.