std::visit函数中的{}和()有什么区别?
What is the difference between {} and () in std::visit function?
下面的代码基本上是 CPP 参考中变体示例的更“简单”版本。它定义了一个 std::variant
类型(第 [1] 行)并使用 std::visit
遍历该类型的向量。在这里,我在 std::visit
函数中使用了一个仿函数(第 [2] 行),试图更好地理解 std::visit
的工作原理。
最让我困惑的是第[4]和[5]行。似乎带花括号的 Print{}
或带圆括号的 Print()
都可以作为 std::visit
函数的第一个参数。后者,即 Print()
,是一个实例化,因此提供一个对象作为第一个参数,这是可以理解的。我不太明白为什么前者 Print{}
也有效。任何人都可以阐明这种特殊性吗?
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]
}
Print()
是对 class Print
的构造函数的调用。 Print{}
是 class Print
的列表初始化。在这种情况下,区别仅在于列表初始化实际上是聚合初始化,并且会初始化 Print
的成员(如果有的话),而构造函数不会。
在这两种情况下,您都传递 Print
.
的实例
下面的代码基本上是 CPP 参考中变体示例的更“简单”版本。它定义了一个 std::variant
类型(第 [1] 行)并使用 std::visit
遍历该类型的向量。在这里,我在 std::visit
函数中使用了一个仿函数(第 [2] 行),试图更好地理解 std::visit
的工作原理。
最让我困惑的是第[4]和[5]行。似乎带花括号的 Print{}
或带圆括号的 Print()
都可以作为 std::visit
函数的第一个参数。后者,即 Print()
,是一个实例化,因此提供一个对象作为第一个参数,这是可以理解的。我不太明白为什么前者 Print{}
也有效。任何人都可以阐明这种特殊性吗?
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]
}
Print()
是对 class Print
的构造函数的调用。 Print{}
是 class Print
的列表初始化。在这种情况下,区别仅在于列表初始化实际上是聚合初始化,并且会初始化 Print
的成员(如果有的话),而构造函数不会。
在这两种情况下,您都传递 Print
.