以下代码适用于gcc
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.enableComplexMapKeySerialization();
Gson mapper = gsonBuilder.create();
//Object to JSON in String
String jsonInString = mapper.toJson(myobject); //myobject=any object of class A
但对于msvc,我还必须使用#include <map>
int main() {
std::map<int, double> dict;
const auto lambda = [&]()
{
decltype(dict)::value_type bar;
};
}
std::remove_reference
否则我得到an error:
#include <map>
#include <type_traits>
int main() {
std::map<int, double> dict;
const auto lambda = [&]()
{
std::remove_reference_t<decltype(dict)>::value_type bar;
};
}
哪个编译器根据标准显示正确的行为?
更新
对于msvc error C2651: 'std::map<int,double,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &': left of '::' must be a class, struct or union
,确实是一个参考,如下面的代码
decltype(dict)
错误
#include <map>
int main()
{
std::map<int, double> dict;
const auto lambda = [&]()
{
decltype(dict) foo;
};
}
如果这确实是错误的行为,那么在使用msvc编译代码时可能会导致nasty bugs, like dangling references。
error C2530: 'foo': references must be initialized
答案 0 :(得分:12)
没有关于decltype
的非括号内应用的特殊规则(即[expr.prim.lambda]/20不适用)。所以我们回到decltype
的通常定义,它要求如果操作数是 id-expression ,则yielding类型只是实体的声明类型,而且&# 39;不是参考类型。因此VC ++是错误的。
注意:是否捕获dict
并不重要,因为¶17:
lambda-expression 的复合语句中的每个 id-expression ,这是一个odr-use(3.2) 将由副本捕获的实体转换为对相应的未命名数据成员的访问权限 闭合类型。 [注意: id-expression 不是odr-use指的是原始实体,永远不会成为 封闭类型。此外,这样的 id-expression 不会导致实体的隐式捕获。 - 结束 注意]
decltype
永远不会使用任何操作数或子操作。这条规则实际上有时会出现问题,例如:如core issue 958所示:
int f (int&); void* f (const int&); int main() { int i; [=] ()-> decltype(f(i)) { return f(i); }; }
此处,decltype(f(i))
使用封闭范围内的非const
i
。但是,由于lambda不是mutable
,因此正文中的i
实际上是const
,因此尾随返回类型不正确。 CWG认为这种情况很少发生,值得解决。