小编Mar*_*rkB的帖子

我是否应该假设从STL容器中删除后立即调用对象的析构函数?

请考虑以下代码:

class T { ... }; // T has a non-trivial destructor

void foo() {
    std::vector<T> v( 5 );
    v.pop_back();

    ...
}
Run Code Online (Sandbox Code Playgroud)

之后v.pop_back(),STL是否保证T::~T()已被要求v.back()?注意:问题保持用于去除元件载体的任何方法(例如resize(),erase()等...)

我正在为我的应用程序编写容器类,我希望它们尽可能符合标准库使用的原则.如果我的集装箱舱没有做出这种保证,是否有任何风险?

c++ destructor stl vector

6
推荐指数
1
解决办法
146
查看次数

等效范围的STL算法

根据定义,std :: equal算法只需要一个'last'迭代器.stackoverflow上的许多帖子表明,要在两个范围之间执行等效,除了调用std :: equal之外,必须首先检查范围是否具有相同的大小.如果随机访问迭代器可用,则不会添加任何材料开销.但是,似乎没有随机访问迭代器,仅使用现有STL算法实现的第一个代码片段将比第二个代码片段慢,后者代表自定义"等效"算法(不是STL的一部分).我的问题是,片段2比仅使用现有STL算法编码的任何算法更有效吗?如果是这样,为什么这个算法不属于STL?

片段1:

template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
    return distance(first1, last1) == distance(first2, last2) &&
        equal( first1, last1, first2 );
}
Run Code Online (Sandbox Code Playgroud)

片段2:

template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
    while ( first1 != last1 && first2 != last2 ) {
       if (!(*first1 == *first2)) return false;
       ++first1; ++first2;
    }
    return first1 == last1 && first2 == last2;
}
Run Code Online (Sandbox Code Playgroud)

注意:我没有检查过,但我很怀疑编译器会优化片段1,以便它生成具有片段2产生的相同性能的代码. …

c++ stl equals

5
推荐指数
1
解决办法
362
查看次数

处理双端队列块大小导致的性能问题

任何在性能关键代码中使用过“deque”的人可能已经注意到(至少在 VS2010 附带的 STL 中)块大小是 16 字节。这是 VS2010 附带的头文件中的实际片段:

#define _DEQUESIZ   (sizeof (value_type) <= 1 ? 16 \
    : sizeof (value_type) <= 2 ? 8 \
    : sizeof (value_type) <= 4 ? 4 \
    : sizeof (value_type) <= 8 ? 2 \
    : 1)    /* elements per block (a power of 2) */
Run Code Online (Sandbox Code Playgroud)

这不是新信息,请参阅关于 deque<T> 的额外间接寻址,了解有关此 decl 为何导致性能问题的更多详细信息。

我想在各种算法中使用双端队列,但如果我仅限于此实现,则不会。规避这个问题的最佳方法是什么?

1) 使用另一个不存在此问题的容器。如果是这样,有人可以给我指出一个没有 GNU 许可证限制的吗?

2) 创建一个新的容器类来解决此限制。这个新的容器类不会成为 std 命名空间的一部分。

3) 编辑“deque”头文件中的_DEQUESIZ 定义。IMO,我认为这是合法的,因为 _DEQUESIZ 的确切规范不是 STL 定义的双端队列概念的一部分。

4) 向双端队列(和关联的迭代器类)添加一个额外的模板参数,以允许在编译时指定块大小。该参数默认为 _DEQUESIZ 的当前定义。我几乎拒绝这个解决方案,因为现在我使用这个混蛋的 …

c++ stl deque

5
推荐指数
1
解决办法
2825
查看次数

c4930可能的编译器错误

我只想在这里发帖,以确保我不会错过任何完全明显的东西(因此会觉得非常愚蠢).这是我写的一些代码的简化版本.

template <int NDIM, typename T = int>
class COORD {
public:
    COORD(T dim0) { m_data[0] = dim0; }
private:
    T m_data[NDIM];
};

template <class COORD>
class NODE {
public:
    NODE(const COORD& c = COORD()) : m_coord(c) {}
private:
COORD m_coord;
};

int main()
{
    const int VAL = 10;
    NODE< COORD<1> > n( COORD<1>( VAL ) ); // warning c4930???
    NODE< COORD<1> > n2( COORD<1>( 10 ) );
    COORD<1> c( VAL );
    NODE< COORD<1> > n3( c );
    return …
Run Code Online (Sandbox Code Playgroud)

c++ warnings visual-studio

4
推荐指数
1
解决办法
570
查看次数

为什么存在两个仅由返回常量不同的隐式转换?

请考虑以下代码:

#include <string>

class WrapperString
{
public:
    WrapperString(const std::string& str) : str_(str) {}

    operator std::string() const { return str_; }
    operator const std::string() const { return str_; }

    std::string get() const { return str_; }
    // error C2373: 'WrapperString::get' : redefinition; different type modifiers
    // const std::string get() const { return str_; }

private:
    std::string str_;
};

int main (int, char *[])
{
    WrapperString w( "Hello" );
    std::string foo = w; // disabling either implicit conversion makes this work
    return …
Run Code Online (Sandbox Code Playgroud)

c++ visual-studio-2010 implicit-conversion

4
推荐指数
1
解决办法
124
查看次数

如果函数在头文件中定义,则内联关键字是否有意义?

所有代码从我读过的内容来看,A1和A2是相同的,但如果A3与A2完全相同,我不会这样做.我知道代码将编译,因为所有A类都被tmemplated.

注意:所有类和方法声明都在.h文件中.

template <typename _Ty>
class A1 {
public:
    A1();
    void foo() { ... }
};


template <typename _Ty>
class A2 {
public:
    A2();
    void foo();
};

template <typename _Ty>
inline void A2<_Ty>::foo() { ... }


template <typename _Ty>
class A3 {
public:
    A3();
    void foo();
};

template <typename _Ty>
void A3<_Ty>::foo() { ... } // note: No inline keyword here.
Run Code Online (Sandbox Code Playgroud)

PS我在stackoverflow上看过这个问题的变种,但不是这个问题.

c++ templates inline

3
推荐指数
1
解决办法
1079
查看次数

归类为病毒的程序是否存在安全漏洞?

我非常惊讶地发现我的AV程序(来自我的ISP,基于Kapersky)检测到我的一个C++程序(即test.exe)有病毒.代码是使用Debug配置从Visual Studio 2010生成的(令人惊讶的是,发行版本没有病毒).报告的病毒是"Gen:Variant.Symmi.3690",这导致任何谷歌搜索完全死路一条.

但是,它让我觉得我的程序可能存在AV工具认为能够被利用的某种安全漏洞(例如缓冲区溢出).

有什么想法吗?

c++ virus

1
推荐指数
1
解决办法
276
查看次数

在确定性多线程应用程序中使用伪随机数引擎?

我正在尝试使用C++ 11随机数生成器来洗牌.我发现(通过查看实现)如果引擎用相同的值播种,则两个引擎产生的随机数序列是相同的.

请考虑以下代码:

DECK::DECK()
{
    // Initialize deck to contain the standard 52 cards in an unsorted manner.
}

void DECK::shuffle()
{
    std::default_random_engine e;
    // Use 'e' to shuffle the deck
}

int main(int, char* [])
{
    DECK d1, d2;
    d1.shuffle();
    d2.shuffle(); 

    // 'd1' and 'd2' are identical!
}
Run Code Online (Sandbox Code Playgroud)

以下是规格:

1)程序输出是确定性的(即相同的输入产生相同的输出).

2)多线程需要同时洗牌的DECK.

3)表现至关重要.我想不使用锁(除非没有其他选择).

由于规范#1,我无法使用系统时间播种std :: default_random_engine.由于规范#2和#3,使引擎成为单身似乎不是一种选择.有没有人有更好的方法来编写这个?

random multithreading stl c++11

1
推荐指数
1
解决办法
273
查看次数

64位计算机上的stl向量大小

我有一个将使用数百万向量的应用程序.

似乎std :: vector的大多数实现使用4个指针(_First,_Last,_End和_Alloc),它们在64位机器上消耗32个字节.对于矢量的大多数"实际"用例,可以分别使用单个指针和两个"unsigned int"字段来存储当前大小和分配的大小.忽略支持自定义分配的潜在挑战(而不是假设分配必须通过全局new&delete运算符),似乎可以构建一个仅使用16个字节的STL兼容向量类(或者最坏的24个字节到支持_Alloc指针).

在我开始编写代码之前,1)是否存在我应该注意的任何陷阱; 2)是否存在开源实现?

c++ stl vector

0
推荐指数
1
解决办法
1403
查看次数