The following code is basically a more "naive" version of the example on variant found on CPP Reference. It defines a std::variant
type (line [1]) and uses std::visit
to iterate through a vector of that type. Here, I used a functor (line [2]) inside the std::visit
function as an attempt for a better understanding of how std::visit
works.
What puzzles me the most lies in lines [4] and [5]. It appears that either Print{}
, with curly brackets, or Print()
, with parentheses, can serve as the first parameter to std::visit
function. The later, i.e., Print()
, is an instantiation and is thus supplying an object as the first parameter, which is comprehensible. I don't quite understand why the former, Print{}
, works too. Can anyone shed some light on this peculiarity?
using var_t = std::variant<int, long, double, std::string>; // [1]
class Print { // [2]
public:
void operator()(int arg) {
std::cout << "Integer is " << arg << '\n';
}
void operator()(double arg) {
std::cout << "Double precision is " << arg << '\n';
}
void operator()(long arg) {
std::cout << "Long type is " << arg << '\n';
}
void operator()(const std::string& arg) {
std::cout << "String is " << arg << '\n';
}
};
std::vector<var_t> vec = {10, 15l, 1.5, "Hello, World", 900}; // [3]
for (auto& v : vec) {
//std::visit(Print{}, v); // [4]
std::visit(Print(), v); // [5]
}
CodePudding user response:
Print()
is a call to constructor of class Print
. Print{}
is list initialization of class Print
. In this case the difference is only int that list initialization actually would be aggregate initialization and would init members of Print
if it had any, the constructor would not.
In both cases you pass an instance of Print
.