[C ++自动声明类型,无需初始化即可声明变量

问题描述 投票:0回答:1

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

换句话说,类似:

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

但是,只有在编译器can推断出类型(例如从函数初始化时)时,这才似乎起作用。

我经常发现自己只需要一个默认构造的,正确类型的变量(通常是一个类成员变量),而这让我不得不做:

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解决方案是否有任何明显的缺点(它必须允许使用模板化函数,但这应该只是一个较小的扩展)?
c++ auto type-deduction
1个回答
0
投票

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

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

向我显示asif()听起来有点像decltype()

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

auto m_collection = decltype(getCollection());

[我必须承认,我对在日常业务中实际使用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

Live Demo on coliru

到目前为止,还好。


我可以在没有类型别名的情况下执行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

Live Demo on coliru

我必须承认它是链接的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

Live Demo at coliru


看起来我可以做到前者,但我想确保它是标准的东西,而不仅仅是gcc扩展。
[AFAIK,decltype()实际上是C ++标准功能(在cppreference.com中提到的内容对我来说算是“证明”。]

除此之外,我使用了最后一个示例进行检查

clang 10.0.0 -std=c++11

    gcc 10.1 -std=c++11
  • msvc v19.24 /std:c++14/std:c++11不是可用选项。]
  • [所有人都通过了CompilerExplorer的检查。
© www.soinside.com 2019 - 2024. All rights reserved.