Home > OS >  What is the difference between {} and () in std::visit function?
What is the difference between {} and () in std::visit function?

Time:11-11

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.

  • Related