我在Effective STL中注意到了
vector是默认情况下应该使用的序列类型.
这是什么意思?似乎忽略效率vector
可以做任何事情.
任何人都可以给我一个vector
不可行的选择但list
必须使用的场景吗?
假设我有std::vector
发言权Vector
现在在对向量(插入或删除)执行某些操作之后,我想检查向量是否为空,并且基于此我想要执行某些操作.
哪种方法更好
方法1
if (Vector.size() == 0){ /* operations */ }
Run Code Online (Sandbox Code Playgroud)
方法2
if (Vector.empty()) { /* operations */ }
Run Code Online (Sandbox Code Playgroud)
哪种方法更好,1
还是2
?
谁能解释为什么不为std :: list实现operator []?我搜索了一下但没有找到答案.实施起来不是太难,或者我错过了什么?
此代码运行0.012秒:
std::list<int> list;
list.resize(100);
int size;
for(int i = 0 ; i < 10000; i++)
size = list.size();
Run Code Online (Sandbox Code Playgroud)
这个为9.378秒:
std::list<int> list;
list.resize(100000);
int size;
for(int i = 0 ; i < 10000; i++)
size = list.size();
Run Code Online (Sandbox Code Playgroud)
在我看来,有可能以这种方式实现std :: list,该大小将存储在私有变量中,但根据这个,每次调用size时都会再次计算.有谁能解释为什么?
我正在使用gcc 4.8.1并经过数小时的调试后发现一个可怕的神秘性能问题,我发现它std::list::size
实际上是作为一个调用实现的std::distance
.
/** Returns the number of elements in the %list. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return std::distance(begin(), end()); }
Run Code Online (Sandbox Code Playgroud)
这令我感到惊讶,因为引用说std :: list :: size的复杂性应该是常量,并且复杂性std::distance
是线性的std::list::iterator
.
我真的很困惑,因为我认为gcc对C++ 11功能有很好的支持,我认为他们没有理由不实现这个功能.
这是引用中还是gcc中的错误?
在后一种情况下:
有这么一个基本的C++ 11功能会缺少这么久的原因吗?
还有第三种可能性,例如:
我可以使用gcc 4.8.1但是标准库的某些旧版本?
我已经将这个简单的方法从C#转换为C++.它读取路径表并填充整数列表(或整数向量的向量).
路径表中的示例行类似于
0 12 5 16 n
Run Code Online (Sandbox Code Playgroud)
我知道有一般这样做的更好的办法,但现在我只想知道为什么我的C++代码正在采取这么多的时间.例如10分钟而不是C#版本的10秒钟.这是我的C++代码.我猜我做的事情有点严重错误.
//Parses the text path vector into the engine
void Level::PopulatePathVectors(string pathTable)
{
// Read the file line by line.
ifstream myFile(pathTable);
for (unsigned int i = 0; i < nodes.size(); i++)
{
pathLookupVectors.push_back(vector<vector<int>>());
for (unsigned int j = 0; j < nodes.size(); j++)
{
string line;
if (getline(myFile, line)) //Enter if a line is read successfully
{
stringstream ss(line);
istream_iterator<int> begin(ss), end;
pathLookupVectors[i].push_back(vector<int>(begin, end));
}
}
}
myFile.close();
}
Run Code Online (Sandbox Code Playgroud)
这是C#版本: …
我刚刚编写了一些代码来测试std :: equal的行为,并且惊讶地走了出来:
int main()
{
try
{
std::list<int> lst1;
std::list<int> lst2;
if(!std::equal(lst1.begin(), lst1.end(), lst2.begin()))
throw std::logic_error("Error: 2 empty lists should always be equal");
lst2.push_back(5);
if(std::equal(lst1.begin(), lst1.end(), lst2.begin()))
throw std::logic_error("Error: comparing 2 lists where one is not empty should not be equal");
}
catch(std::exception& e)
{
std::cerr << e.what();
}
}
Run Code Online (Sandbox Code Playgroud)
输出(给我一个惊喜):
Error: comparing 2 lists where one is not empty should not be equal
Run Code Online (Sandbox Code Playgroud)
观察:为什么std :: equal首先检查2个容器是否相同size()
?有合理的理由吗?
最近,我注意到我的程序具有很大的性能下降,因为版本低于5的gcc的标准库实现产生list::size()
了O(n)
。
我正在使用CentOS 7.2,其默认gcc版本为4.8.5。因此,我安装了scl和devtoolset-7,并重建了程序。但是,我发现list::size()
程序中仍然是一个O(n)
方法,即使我显式设置_GLIBCXX_USE_CXX11_ABI
为1。
为什么?这很奇怪。
似乎std::string
是位于的仅标头文件Community/VC/Tools/MSVC/?/include/xstring
,所有生成的代码都应包含在构建目标中。
如果我是对的,Microsoft如何保证下一个Visual Studio版本不会更改xstring
以及其std::string
内部结构?
更新1:
我对此问题有很多反对意见,所以让我解释一下为什么我决定问这个问题。
我面临着奇怪的崩溃,而且我不明白为什么会这样。我使用最新的Qt 5.13.0(MSVC2017_x64),并且我使用Visual Studio 2017编译了一些外部库。所有库都已/MDd
通过dumpbin
util 进行了检查。
当我尝试运行任何调用Qt库和的代码时std::string
,我得到了错误的结果(并最终崩溃)。
这是一个非常简单的示例:
#include <QApplication.h>
int main(int argc, char** argv) {
QString s1("Test");
std::string s2 = s1.toStdString(); // here we have s2 variable with wrong internal structure
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的想法是QtCore DLL库具有std::string
与std::string
Visual Studio 2017 不兼容的内部结构。但是Qt是使用Visual Studio 2017创建的(可能与我当前的Visual Studio不同,因为有几个次要版本),所以我决定问一下它们是否兼容。
更新2:
问题出在_ITERATOR_DEBUG_LEVEL
。看起来Qt是用2级编译的,而我所有的外部库和应用程序都是用0级编译的。
此选项影响许多C ++标准库类的内部结构,并带来此类副作用。因此,当我们进入内部toStdString()
并创建时std::string
,我们具有2级和一个内部结构。当我们在应用程序代码中时,我们具有0级和另一个内部结构。我们将具有一种内部结构的对象分配给具有另一种内部结构的对象。
无论如何,我现在对某些内部结构有了更好的了解。
在学校,我了解到一个链表包含一个指向列表中下一个元素的指针的元素,链表的缺点是找到大小具有线性复杂性,因为你必须遍历每个元素并计算.但是我注意到在C++ 11中,std :: list.size()具有恒定的复杂性.这怎么可能?
c++ ×10
stl ×4
list ×3
c++11 ×2
gcc ×2
vector ×2
c# ×1
io ×1
linked-list ×1
performance ×1
qt ×1
redhat-dts ×1
size ×1
visual-c++ ×1