解决"Error C2338 The C++ Standard forbids containers of const elements ..."

解决"Error C2338 The C++ Standard forbids containers of const elements because allocator"问题

最近在用Visual Studio 2017编译Brofiler(一个C++的Profiler)时,遇到了一些问题,其中一个就是这个Error C2338

原因

因为在STL容器模板中使用了const,在C++11的标准里,这是禁止的!而老版本的Visual Studio并没有这么严格,所以一般可以编译过。这里顺便列一下最新的标准里,模板参数的要求,以后写代码时尽量注意一下。

StandardRequirement for T
C++03any type
C++11any non-const, non-reference object type
C++14any non-const object type
C++17any cv-unqualified object type

解决

由于C++模板的特殊性,一般模板的报错信息都非常“谜”。在我本机,报错信息是指向了xmemory0文件,但其实不是这个文件出错,而是因为我们自身的代码在STL容器模板中使用了const导致出错的。
可以通过文本查找“<const”,基本能找到项目中大部分在模板中使用了const的代码,将其中的const去掉即可。如果找不全,可以试下:< constconst>const >等情况,或者通过正则表达式来查找。

例如在Brofiler 1.1.2的源码中,就有2处地方使用了const。注意去掉了容器定义里的const后,一般还会导致部分容器使用的代码报错,我们可以用const_cast来去掉代码里的const限定,如下:

// 文件:Core.h

// FIX Error C2338
//typedef MemoryPool<const EventData*, 32> CategoryBuffer;
typedef MemoryPool<EventData*, 32> CategoryBuffer;

BRO_INLINE void RegisterCategory(const EventData& eventData) 
{ 
	// FIX Error C2338
	//categoryBuffer.Add() = &eventData;
	categoryBuffer.Add() = const_cast<EventData*>(&eventData);
}
// 文件:Sampler.cpp

OutputDataStream& Sampler::Serialize(OutputDataStream& stream)
{
	// ...

	// FIX Error C2338
	//std::vector<const Symbol * const> symbols;
	std::vector<Symbol*> symbols;
	for each (DWORD64 address in addresses)
		if (auto symbol = symEngine.GetSymbol(address))
			//symbols.push_back(symbol);
			symbols.push_back(const_cast<Symbol*>(symbol));

	// ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值