STL - 以下代码有啥问题?

Posted

技术标签:

【中文标题】STL - 以下代码有啥问题?【英文标题】:STL - what is the problem of the following code?STL - 以下代码有什么问题? 【发布时间】:2010-12-17 20:17:17 【问题描述】:
#include "stdafx.h"
#include <string>
#include <map>
using namespace std;

class NiftyEmailProgram 
private:
    typedef map<string, string> NicknameMap;
    NicknameMap nicknames;

public:
    void ShowEmailAddress(const string& nickname) const
    
        NicknameMap::const_iterator i = nicknames.find(nickname);

        if ( i != nicknames.end() )
        
        
    

;

int main(int argc, char* argv[])

    printf("Hello World!\n");
    return 0;

当我在 VC6.0 中编译上述代码时,我看到了大量的警告。如果我使用警告级别 4 并将所有警告视为错误,则 STLFilt 的输出错误如下:

Compiling...
t3.cpp
c:\devstudio_6.0\vc98\include\xtree(118): error C2220: warning treated as error - no object file generated
    c:\devstudio_6.0\vc98\include\map(46): see reference to class template instantiation 'map<string,string>' being compiled
    C:\TEMP\t3\t3.cpp(12): see reference to class template instantiation 'map<string,string>' being compiled
Error executing cl.exe.  


t3.exe - 1 error(s), 26 warning(s)
Tool returned code: 0

现在,这段代码有什么问题,我该如何解决?

谢谢

【问题讨论】:

你为什么使用 12 年的编译器? 代码读起来很好。 VC 6.0 很可能是罪魁祸首。 VC 6 是罪魁祸首。 VC 8 弃用了一些完全有效的 STL 函数(例如std::copy)。这让我每天都很烦。您必须根据具体情况禁用警告。 您应该询问他们是否计划升级到 Windows 98。看看它与 VC6 的现代性。 大家好,不要因为他保留旧的编译器而责备他——有时你依赖的库无法升级,或者大量代码不会花费——有效升级。附言我已经对我的答案进行了补充,请查看。 【参考方案1】:

尝试发布未经处理的警告。

但是,我也记得我在 &lt;map&gt; 中收到了来自 &lt;xtree&gt; 的一些 4 级警告,可以安全地忽略(IIRC 是 C4702,这是无害的)。

为了避免警告,我在 STL #includes 周围放置了一些适当的 #pragma warning 指令(包含在正确的 #ifdefs 中,以便仅在 MSVC++ 上考虑它们,感谢 @Alexandre C. 提醒我):

#ifdef _MSC_VER
    //Disable the C4702 warning for the following headers
    #pragma warning(push)
    #pragma warning(disable:4702)
#endif // _MSC_VER
//map STL container
#include <map>
//list STL container
#include <list>
//vector STL container
#include <vector>
#ifdef _MSC_VER
    #pragma warning(pop)
#endif

您也可以在该部分中将警告级别降低到 3(甚至更低):

#ifdef _MSC_VER
    // Lower the warning level to 3 just for this section
    #pragma warning(push, 3)
#endif
//map STL container
#include <map>
//list STL container
#include <list>
//vector STL container
#include <vector>
#ifdef _MSC_VER
    #pragma warning(pop)
#endif // _MSC_VER

有关详细信息,请参阅documentation of #pragma warning

【讨论】:

为了可移植性,您可以将#pragma#ifdef _MSC_VER ... #endif 分开。 @Alexandre C.:嗯,你说的很对,我现在就修。 抱歉吹毛求疵,但是当您使用它时,请养成为特定版本启用它的习惯,因为这在 MSVC7 上表现良好。 @André Caron:我在 MSVC7.1 上也收到了第 4 级警告,所以我会保持原样,也因为一般来说,您希望标准库头文件是经过充分测试,您可能从他们那里得到的警告并不重要。【参考方案2】:

如果我没记错的话,由 STL 创建的损坏的函数名称很容易超过一些内置限制,这就是触发警告的原因。很遗憾,您使用 STLFilt 来阻止我们看到编译器产生的实际警告。

我发现的唯一解决方法是使用 typedef 和/或派生类来缩短模板中使用的名称。

正如其他人所提到的,最好和最简单的解决方法是升级你的编译器。

编辑:我在自己的 VC6 上试过这个,错误和我记忆中的一模一样:

c:\program files\microsoft visual studio\vc98\include\xtree(118) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,
std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<cha
r,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::basi
c_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
        c:\program files\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<
char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<cha
r> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,std::allocato
r<char> > >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' being compiled

我之前提到的解决方法是不够的,因为使用最短的类名,迭代器的名称仍然超过 255 个字符。解决办法是把这个放在#include &lt;map&gt;之前:

#pragma warning(disable:4786)

【讨论】:

总警告信息的大小为 60285,我不允许在这里发布这么大的文本。谢谢 @q0987: 你可以把它贴在 pastebin 或类似的地方。 @q0987,我想大多数警告都是重复的,你不能只发布一两个吗?

以上是关于STL - 以下代码有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

在oi/acm中,有啥冷门但好用的stl函数

以下代码有啥问题?

以下两行有啥问题[重复]

以下代码的矢量化有啥好处吗?

在这里使用迭代器有啥问题

代码有啥问题