C++ 中是否有像 JavaScript 中那样的完全泛型对象?
Are there completely-generic objects in C++ like in JavaScript?
我是 C++ 的新手,但在 Javascript 方面有一些经验。
在JavaScript,当我写:
var object = {};
我创建了一个“完全通用”的对象,因为它没有 members/features,但它 可以 通过添加我们喜欢的任何成员稍后。
我可以在 C++ 中创建或模拟这种对象吗?
JavaScript 是动态类型,而 C++ 是静态类型。
在JavaScript中,正如你在例子中所展示的,你只需要写变量名,而不需要添加类型。之后,您可以分配一个字符串值,也可以分配一个 int 值或任何其他类型的值。
示例:
var first;
var second;
在C++中,必须用变量声明变量的类型。
示例:
std::string str_value;
float float_value;
int int_value;
答案大多是-不,你不能。。在 JavaScript 中,Object
可以比作字典或从键到类型化值的映射,值及其类型都可以在 运行 时设置。
您可以 在 C++ 中创建任意类型值的字典,使用 std::any
的类型擦除功能,以及作为键的字符串。使用这种方法,您可以编写:
using generic_object = std::unordered_map<std::string, std::any>
generic_object object;
object["foo"] = 123;
object["bar"] = [](char c) -> char { return c+1; };
object["baz"] = std::vector<int>{4,5,6,7};
std::any_cast<std::vector<int>>(object["bar"])[2] = 3 + std::any_cast<int>(object["foo"]);
您不能在通用对象的新字段上使用简单明了的 C++ 语法,即您不能写:
using generic_object = /* whatever */;
generic_object object;
object.foo = 123; // Compilation errors start here!
object.bar = []() -> char { return c+1; }
object.baz = std::vector<int>{4,5,6,7};
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
您可能习惯于 JavaScript。相反,它必须是:
struct {
int foo;
char (*bar)(char c);
std::vector<int> baz;
} object;
object.foo = 123;
object.bar = []() -> char { return c+1; }
object.baz = std::vector<int>{4,5,6,7};
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
这就是 C++ 的“静态类型”特性。或者更进一步,避免函数指针:
struct {
int foo { 123 };
char bar(char c) const { return c+1; }
std::vector<int> baz {4,5,6,7};
} object;
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
使用清晰类型的方法,而不是我上面描述的“任意字典”;那个会很麻烦,很慢,而且大多数人都不喜欢。
另请参阅:
What is the difference between statically typed and dynamically typed languages?
我是 C++ 的新手,但在 Javascript 方面有一些经验。
在JavaScript,当我写:
var object = {};
我创建了一个“完全通用”的对象,因为它没有 members/features,但它 可以 通过添加我们喜欢的任何成员稍后。
我可以在 C++ 中创建或模拟这种对象吗?
JavaScript 是动态类型,而 C++ 是静态类型。
在JavaScript中,正如你在例子中所展示的,你只需要写变量名,而不需要添加类型。之后,您可以分配一个字符串值,也可以分配一个 int 值或任何其他类型的值。
示例:
var first;
var second;
在C++中,必须用变量声明变量的类型。
示例:
std::string str_value;
float float_value;
int int_value;
答案大多是-不,你不能。。在 JavaScript 中,Object
可以比作字典或从键到类型化值的映射,值及其类型都可以在 运行 时设置。
您可以 在 C++ 中创建任意类型值的字典,使用 std::any
的类型擦除功能,以及作为键的字符串。使用这种方法,您可以编写:
using generic_object = std::unordered_map<std::string, std::any>
generic_object object;
object["foo"] = 123;
object["bar"] = [](char c) -> char { return c+1; };
object["baz"] = std::vector<int>{4,5,6,7};
std::any_cast<std::vector<int>>(object["bar"])[2] = 3 + std::any_cast<int>(object["foo"]);
您不能在通用对象的新字段上使用简单明了的 C++ 语法,即您不能写:
using generic_object = /* whatever */;
generic_object object;
object.foo = 123; // Compilation errors start here!
object.bar = []() -> char { return c+1; }
object.baz = std::vector<int>{4,5,6,7};
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
您可能习惯于 JavaScript。相反,它必须是:
struct {
int foo;
char (*bar)(char c);
std::vector<int> baz;
} object;
object.foo = 123;
object.bar = []() -> char { return c+1; }
object.baz = std::vector<int>{4,5,6,7};
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
这就是 C++ 的“静态类型”特性。或者更进一步,避免函数指针:
struct {
int foo { 123 };
char bar(char c) const { return c+1; }
std::vector<int> baz {4,5,6,7};
} object;
object.baz[2] = 3 + object.foo;
std::cout << "'a' becomes " << object.bar('a') << '\n';
使用清晰类型的方法,而不是我上面描述的“任意字典”;那个会很麻烦,很慢,而且大多数人都不喜欢。
另请参阅:
What is the difference between statically typed and dynamically typed languages?