我正在编写一些C++ 11代码,这些代码对其性质的假设std::string是有效的,但代表了在C++ 11中改变的行为.在早期,libstdc ++的basic_string实现符合98/03的要求,但不符合更严格的C++ 11要求.
据我了解,libstdc ++修复了问题basic_string.问题是人们使用的库有许多版本没有实现此修复.而且我的代码可能会以许多不愉快的方式无声地失败.
我想有一个static_assert火,如果用户尝试编译我的图书馆对的libstdc ++的那些不符合的版本.如何检测版本,同样重要的是,我应该查找哪个版本?
我仍在尝试决定我的(home)项目是否应该使用UTF-8字符串(在必要时使用std :: string和其他特定于UTF-8的函数实现)或一些16位字符串(实现为std: :wstring的).该项目是一种编程语言和环境(如VB,它是两者的结合).
有一些愿望/约束:
目前,我正在使用std :: string,目的是仅在必要时使用UTF-8操作函数.它需要更少的内存,似乎是许多应用程序正在进行的方向.
我需要以键值格式存储字符串.所以我正在使用如下的地图.
#include<map>
using namespace std;
int main()
{
map<string, string> m;
string s1 = "1";
string v1 = "A";
m.insert(pair<string, string>(s1, v1)); //Error
}
Run Code Online (Sandbox Code Playgroud)
我在插入行时遇到错误
错误C2784:'bool std :: operator <(const std :: _ Tree <_Traits>&,const std :: _ Tree <_Traits>&)':无法推断'const std :: _ Tree <_Traits>&'的模板参数来自'const std :: string'
我也尝试过make_pair函数,但是这也报告了同样的错误.
m.insert(make_pair(s1, v1));
Run Code Online (Sandbox Code Playgroud)
请告诉我什么是错的,以及解决上述问题的方法是什么.解决了上述问题后,我可以使用下面的方法来检索基于密钥的值
m.find(s1);
Run Code Online (Sandbox Code Playgroud) 我正在写一个Cocos2D-X游戏,其中玩家,敌人和其他角色将他们的属性存储在a中CCMutableDictionary,这有点像装饰类std::map<std::string, CCObject*>.可以通过该CCMutableDictionary::objectForKey(const std::string& key)方法访问字典中的值.
现在,在我的许多.cpp文件包含的头文件中,我有一些const char * const字符串用于访问字典中的值,如下所示:
// in Constants.h
const char* const kAttributeX = "x";
const char* const kAttributeY = "y";
// in a .cpp file
CCObject* x = someDictionary->objectForKey(kAttributeX);
Run Code Online (Sandbox Code Playgroud)
所以,如果我错了,请纠正我,但每当我使用a 调用上述方法之一时,std::string正在调用复制构造函数并且临时std::string存在于堆栈中,对吧?objectForKeyconst char* const
如果是这样,我觉得如果那些常量属性键已经是std::string对象,那么在运行时它会更有效.但是我该如何以正确的方式做到这一点?
在Constants.h文件中定义它们,如下所示编译好,但我觉得有些事情是不对的:
// in Constants.h
const std::string kAttributeX = "x";
const std::string kAttributeY = "y";
Run Code Online (Sandbox Code Playgroud)
如果已经提出这个问题我很抱歉.我似乎找不到我在StackOverflow上寻找的确切答案.
回应中的讨论
如何以跨平台友好的方式处理C/C++中的Unicode字符串?
我正在尝试将UTF-8字符串分配给环境中的std::string变量Visual Studio 2010
std::string msg = "?????";
但是,当我查看字符串视图调试器时,我只看到"?????" 我将文件保存为Unicode(带签名的UTF-8),我使用字符集"使用unicode字符集"
"महसुस"是一种尼泊尔语言,它包含5个字符,占用15个字节.但是visual studio调试器将msg大小显示为5
我的问题是:
如何使用std :: string只存储utf-8而不需要操作它?
这是我的代码:
#include <iostream>
int main(int argc, char const *argv[])
{
std::string s = "hello";
std::cout << s.size() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,我可以编译并运行它clang++,虽然我甚至不添加#include <string>.
那么,是否有必要添加#include <string>才能使用std::string?
这个问题有可能是重复的,例如从c ++中的字符串中删除双引号,
但是我看到的所有asnwers都没有解决我的问题
我有一个字符串列表,其中一些是双引号而另一些则不是,引号总是在开头并结束
std::vector<std::string> words = boost::assign::list_of("words")( "\"some\"")( "of which")( "\"might\"")("be quoted");
Run Code Online (Sandbox Code Playgroud)
我正在寻找最有效的方法来删除报价.这是我的尝试
for(std::vector<std::string>::iterator pos = words.begin(); pos != words.end(); ++pos)
{
boost::algorithm::replace_first(*pos, "\"", "");
boost::algorithm::replace_last(*pos, "\"", "");
cout << *pos << endl;
}
Run Code Online (Sandbox Code Playgroud)
我能做得比这更好吗?我可能有数十万个字符串要处理.它们可能来自文件或数据库.示例中的std :: vector仅用于说明目的.
我对将std :: string作为const引用返回有疑问.
class sample
{
public:
std::string mString;
void Set(const std::string& s)
{
mString = s;
}
std::string Get()
{
return mString;
}
};
Run Code Online (Sandbox Code Playgroud)
在Set函数中,我将std :: string作为const引用传递给const,因为它的值在函数内部没有变化.
而在Get功能中,实际上我在这里很困惑.返回std :: string作为值更有意义.但我不确定,通过传递字符串作为const引用有任何好处.通过回转字符串作为参考将增加exectuion速度,我想是的,但我不确定.但是将它作为'const返回可以为此带来任何好处?
如何修复Visual Studio 2012错误LNK2019:未解析的外部符号"__declspec(dllimport)public:class std :: basic_string?
我一直在编译一个包含一个exe和几个静态lib项目的解决方案,其中exe依赖于Visual Studio 2008.静态库包括:
我将解决方案加载到Visual Studio 2012中并编译了解决方案中的所有项目,但是当我尝试链接exe时,我在标准C++库中收到有关未解析符号的错误,如下面的输出.
我发现很多人都有像这样的未解决的符号,但没有一个修复对我有效.到目前为止我尝试过的修复包括
Visual Studio 2012链接器的输出...
1>ace_funcs.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:LBR' specification
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>ComponentX-Win32.lib(MyOrgConsoleSktServer.obj) : warning LNK4049: locally defined symbol ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)) imported
1>ComponentY-Win32.lib(ORBSingleton.obj) : warning LNK4049: locally defined symbol …Run Code Online (Sandbox Code Playgroud) stdstring unresolved-external lnk2019 c++-standard-library visual-studio-2012
因此,C++ 14引入了许多用户定义的文字,其中一个是用于创建对象的"s"文字后缀std::string.根据文档,它的行为与构造std::string对象完全相同,如下所示:
auto str = "Hello World!"s; // RHS is equivalent to: std::string{ "Hello World!" }
Run Code Online (Sandbox Code Playgroud)
当然,构建一个未命名的std::string对象可以在C++ 14之前完成,但由于C++ 14的方式简单得多,我认为实际上会有更多的人考虑std::string在现场构建对象,这就是为什么我认为有必要提问这个.
所以我的问题很简单:在什么情况下构建一个未命名的std::string对象是一个好的(或坏的)想法,而不是简单地使用C风格的字符串文字?
考虑以下:
void foo(std::string arg);
foo("bar"); // option 1
foo("bar"s); // option 2
Run Code Online (Sandbox Code Playgroud)
如果我是正确的,第一个方法将调用适当的构造函数重载std::string来在foo范围内创建一个对象,第二个方法将首先构造一个未命名的字符串对象,然后foo从中移动构造的参数.虽然我确信编译器非常擅长优化这样的东西,但是,第二个版本似乎需要额外的移动,而不是第一个替代(当然不像移动是昂贵的).但同样,在使用合理的编译器编译之后,最终结果最有可能被高度优化,并且无论如何都没有冗余和移动/复制.
另外,如果foo被重载以接受右值引用怎么办?在那种情况下,我认为打电话是有意义的foo("bar"s),但我可能是错的.
考虑以下:
std::cout << "Hello World!" << std::endl; // option 1
std::cout << "Hello World!"s << std::endl; // option 2
Run Code Online (Sandbox Code Playgroud)
在这种情况下,std::string对象可能cout通过右值引用传递给运算符,第一个选项可能传递指针,因此两者都是非常便宜的操作,但第二个选项首先需要额外构建对象.这可能是一种更安全的方式(?). …