`auto` 和 `std::any` 有什么区别?

What is the difference between `auto` and `std::any`?

我最近遇到了 std::any class,在 C++17 中引入,基于 boost::any。这个class可以“持有任何类型的实例”并且auto自动推断出变量的数据类型。

那么主要区别是什么?有什么优缺点?

std::anyauto 是完全不同的结构。


std::any是容器类型,可以容纳任何类型的对象:

std::any a = 42;        // a holds an int, but type is std::any
a = std::string{"hi"};  // ok, a holds a string now

std::any持有的对象的类型可以在程序执行期间改变。


auto 是指定占位符类型的关键字。带有auto的变量的类型是用来初始化变量的值的类型:

auto a = 42;            // a is int, for the entirety of the program
a = std::string{"hi"};  // error, a has type int

此类型是静态确定的,即在编译时确定,并且在程序执行期间永远不会更改。


这些构造不可互换,因此它们有不同的用例,您无法有意义地比较一个与另一个的优缺点。

如果你写:

auto a = 42;
a = "some string";

你得到一个编译错误,因为 aint 类型的变量,你不能给它分配一个字符串。 auto 关键字仅表示编译器将为您决定使用哪种类型。

现在,如果你写:

std::any a = 42;
a = "some string";

这会起作用,因为 a 的类型是 std::any,这是一个复杂的 class 类型,它使用模板在幕后为您存储任何类型。不用说,它比 int 复杂得多,您应该只在绝对必要时才使用它。

What is the main difference?

主要区别在于 auto 是编译时的事情,而 std::any 是运行时的事情,但可以说它们在逻辑上做同样的事情:它们可以存储任何类型的变量.

std::any 是一种现代的 type-safe 构造,适用于您希望拥有一个其类型可能在 run-time 处更改的变量的情况。几个例子 use-cases 是:

  1. 从可以具有任何类型的 file/Gui 读取特定值
  2. 模拟脚本语言的动态类型行为
  3. 一个很好的 type-safe 候选包装来自遗留库的 void* 变量

另一方面,auto 是一种编译器机制,可以在编译时进行类型推导,并将其用于auto 之后使用的变量。也就是说,使用auto定义的变量类型,之后是不能改变的。