如何在 C++ 中模拟解构?
How can I emulate destructuring in C++?
在JavaScript ES6 中,有一个语言特性被称为destructuring。它也存在于许多其他语言中。
在JavaScript ES6中,它看起来像这样:
var animal = {
species: 'dog',
weight: 23,
sound: 'woof'
}
//Destructuring
var {species, sound} = animal
//The dog says woof!
console.log('The ' + species + ' says ' + sound + '!')
我可以在 C++ 中做些什么来获得类似的语法并模拟这种功能?
主要是 std::map
和 std::tie
:
#include <iostream>
#include <tuple>
#include <map>
using namespace std;
// an abstact object consisting of key-value pairs
struct thing
{
std::map<std::string, std::string> kv;
};
int main()
{
thing animal;
animal.kv["species"] = "dog";
animal.kv["sound"] = "woof";
auto species = std::tie(animal.kv["species"], animal.kv["sound"]);
std::cout << "The " << std::get<0>(species) << " says " << std::get<1>(species) << '\n';
return 0;
}
对于 std::tuple
(或 std::pair
)对象的特定情况,C++ 提供了看起来类似的 std::tie
函数:
std::tuple<int, bool, double> my_obj {1, false, 2.0};
// later on...
int x;
bool y;
double z;
std::tie(x, y, z) = my_obj;
// or, if we don't want all the contents:
std::tie(std::ignore, y, std::ignore) = my_obj;
我不了解与您介绍的符号完全相同的方法。
恐怕你不能像在JavaScript(顺便说一句,似乎是new technology in JS)中习惯的那样。原因是在 C++ 中,您不能像在
中那样在 structure/object/assignment 表达式中分配多个变量
var {species, sound} = animal
然后使用 species
和 sound
作为 简单 变量。目前 C++ 根本没有该功能。
您可以对结构 and/or 对象进行赋值,同时重载它们的赋值运算符,但我看不出有什么方法可以模拟那种确切的行为(截至今天)。考虑提供类似解决方案的其他答案;也许这适合您的要求。
另一种可能是
#define DESTRUCTURE2(var1, var2, object) var1(object.var1), var2(object.var2)
可以像这样使用:
struct Example
{
int foo;
int bar;
};
Example testObject;
int DESTRUCTURE2(foo, bar, testObject);
生成 foo
和 bar
的局部变量。
当然,它仅限于创建所有相同类型的变量,尽管我想您可以使用 auto
来解决这个问题。
并且该宏仅限于执行两个变量。因此,您必须创建 DESTRUCTURE3、DESTRUCTURE4 等以覆盖任意数量的内容。
我个人不喜欢最终的代码风格,但它相当接近 JavaScript 功能的某些方面。
在 C++17 中,这称为 structured bindings,它允许以下内容:
struct animal {
std::string species;
int weight;
std::string sound;
};
int main()
{
auto pluto = animal { "dog", 23, "woof" };
auto [ species, weight, sound ] = pluto;
std::cout << "species=" << species << " weight=" << weight << " sound=" << sound << "\n";
}
在JavaScript ES6 中,有一个语言特性被称为destructuring。它也存在于许多其他语言中。
在JavaScript ES6中,它看起来像这样:
var animal = {
species: 'dog',
weight: 23,
sound: 'woof'
}
//Destructuring
var {species, sound} = animal
//The dog says woof!
console.log('The ' + species + ' says ' + sound + '!')
我可以在 C++ 中做些什么来获得类似的语法并模拟这种功能?
主要是 std::map
和 std::tie
:
#include <iostream>
#include <tuple>
#include <map>
using namespace std;
// an abstact object consisting of key-value pairs
struct thing
{
std::map<std::string, std::string> kv;
};
int main()
{
thing animal;
animal.kv["species"] = "dog";
animal.kv["sound"] = "woof";
auto species = std::tie(animal.kv["species"], animal.kv["sound"]);
std::cout << "The " << std::get<0>(species) << " says " << std::get<1>(species) << '\n';
return 0;
}
对于 std::tuple
(或 std::pair
)对象的特定情况,C++ 提供了看起来类似的 std::tie
函数:
std::tuple<int, bool, double> my_obj {1, false, 2.0};
// later on...
int x;
bool y;
double z;
std::tie(x, y, z) = my_obj;
// or, if we don't want all the contents:
std::tie(std::ignore, y, std::ignore) = my_obj;
我不了解与您介绍的符号完全相同的方法。
恐怕你不能像在JavaScript(顺便说一句,似乎是new technology in JS)中习惯的那样。原因是在 C++ 中,您不能像在
中那样在 structure/object/assignment 表达式中分配多个变量var {species, sound} = animal
然后使用 species
和 sound
作为 简单 变量。目前 C++ 根本没有该功能。
您可以对结构 and/or 对象进行赋值,同时重载它们的赋值运算符,但我看不出有什么方法可以模拟那种确切的行为(截至今天)。考虑提供类似解决方案的其他答案;也许这适合您的要求。
另一种可能是
#define DESTRUCTURE2(var1, var2, object) var1(object.var1), var2(object.var2)
可以像这样使用:
struct Example
{
int foo;
int bar;
};
Example testObject;
int DESTRUCTURE2(foo, bar, testObject);
生成 foo
和 bar
的局部变量。
当然,它仅限于创建所有相同类型的变量,尽管我想您可以使用 auto
来解决这个问题。
并且该宏仅限于执行两个变量。因此,您必须创建 DESTRUCTURE3、DESTRUCTURE4 等以覆盖任意数量的内容。
我个人不喜欢最终的代码风格,但它相当接近 JavaScript 功能的某些方面。
在 C++17 中,这称为 structured bindings,它允许以下内容:
struct animal {
std::string species;
int weight;
std::string sound;
};
int main()
{
auto pluto = animal { "dog", 23, "woof" };
auto [ species, weight, sound ] = pluto;
std::cout << "species=" << species << " weight=" << weight << " sound=" << sound << "\n";
}