C++声明变量时自动类型推断而不初始化

C++ auto type deduction when declaring variables without initialisation

本文关键字:初始化 类型 声明 变量 C++      更新时间:2023-10-16

我实际上非常喜欢C++中的自动类型推导,我可以从函数中获得任意复杂的返回类型,但在调用函数时不必担心类型是什么。

换句话说,像这样:

std::vector<std::map<std::string, std::string>> getCollection() { ... }
auto myMapArray = getCollection();

但是,这似乎仅在编译器可以推断类型时才有效,例如从函数初始化时。

我经常发现自己的情况是,我只想要一个正确类型的默认构造变量(通常是类成员变量(,这让我很痛苦:

std::vector<std::map<std::string, std::string>> getCollection();
std::vector<std::map<std::string, std::string>> m_collection;

在这种情况下。但我知道除了使用typedef或更现代的using之外,没有其他方法可以避免长类型名称:

typedef std::vector<std::map<std::string, std::string>> VecOfMaps;
using VecOfMaps = std::vector<std::map<std::string, std::string>>;
:
VecOfMaps m_collection;

似乎允许变量的类型推导很有用,就好像它是从函数返回的东西一样,例如:

std::vector<std::map<std::string, std::string>> getCollection() { ... }
auto m_collection = asif(getCollection);

不需要提供参数,因为所有重载都需要返回相同的类型。所以我的问题真的是:

  • 有没有比类型别名更好的方法来做到这一点?
  • asif解决方案是否有任何明显的缺点(它必须允许模板化功能,但这应该只是一个次要的扩展(?

关于您的评论:

似乎允许变量的类型推导很有用,就好像它是从函数返回的东西一样,例如:

std::vector<std::map<std::string, std::string>> getCollection() { ... }
auto m_collection = asif(getCollection);

在我看来,asif()听起来有点像decltype((。

在这种情况下,它是必需的函数的返回类型,因此它应该是

decltype(getCollection()) m_collection;

我必须承认,我对decltype()在日常业务中的实际使用没有经验,并且摆弄了一下自己(出于好奇(,最终得出:

#include <iostream>
#include <map>
#include <string>
#include <vector>
auto func() { return std::vector<std::map<std::string, std::string>>(); }
struct Class {
typedef decltype(func()) VarType;
VarType var;
};
int main()
{
Class obj;
std::cout << "type of Class::var: " << typeid(obj.var).name() << 'n';
}

其输出为:

type of Class::var: St6vectorISt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_St4lessIS6_ESaISt4pairIKS6_S6_EEESaISD_EE

科里鲁的现场演示

目前为止,一切都好。


我可以在没有类型别名的情况下执行decltype(fn()) variable;吗?

#include <iostream>
#include <map>
#include <string>
#include <vector>
auto func() { return std::vector<std::map<std::string, std::string>>(); }
struct Class {
decltype(func()) var;
};
int main()
{
Class obj;
std::cout << "type of Class::var: " << typeid(obj.var).name() << 'n';
}

输出:

type of Class::var: St6vectorISt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_St4lessIS6_ESaISt4pairIKS6_S6_EEESaISD_EE

科里鲁的现场演示

我必须承认,这是链接的 decltype(( 文档中的示例之一,它让我确信这一点。

此外,我想提一下decltype()是(类似于例如sizeof( 编译时仅类型求值。因此,如果根本没有可用的func()实现,它甚至可以工作:

#include <iostream>
#include <map>
#include <string>
#include <vector>
std::vector<std::map<std::string, std::string>> func();
struct Class {
decltype(func()) var;
};
int main()
{
Class obj;
std::cout << "type of Class::var: " << typeid(obj.var).name() << 'n';
}

输出:

type of Class::var: St6vectorISt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_St4lessIS6_ESaISt4pairIKS6_S6_EEESaISD_EE

科里鲁的现场演示


看起来我可以做前者,但我想确保它是一个标准的东西,而不仅仅是一个 gcc 扩展。

据我所知,decltype()实际上是一个C++标准功能(自 C++11 以来,cppreference.com中提到的事实对我来说算作"证据"(。

除此之外,我使用最后一个样本来检查它

  • 叮当 10.0.0-std=c++11
  • GCC 10.1-std=c++11
  • MSVC v19.24/std:c++14(/std:c++11不是可用的选项。

所有人都通过了编译器资源管理器上的此检查。

相关文章: