实际上,我真的很喜欢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
解决方案是否有任何明显的缺点(它必须允许使用模板化函数,但这应该只是一个较小的扩展)?[似乎允许变量的类型推导好像是从函数返回的东西一样有用,例如:
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
到目前为止,还好。
我可以在没有类型别名的情况下执行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扩展。[AFAIK,decltype()
实际上是C ++标准功能(在cppreference.com
中提到的内容对我来说算是“证明”。]除此之外,我使用了最后一个示例进行检查
clang 10.0.0
-std=c++11
-std=c++11
/std:c++14
(/std:c++11
不是可用选项。]