小编Fra*_*eux的帖子

迭代时从STL集中删除元素

我需要浏览一个集合并删除符合预定义条件的元素.

这是我写的测试代码:

#include <set>
#include <algorithm>

void printElement(int value) {
    std::cout << value << " ";
}

int main() {
    int initNum[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::set<int> numbers(initNum, initNum + 10);
    // print '0 1 2 3 4 5 6 7 8 9'
    std::for_each(numbers.begin(), numbers.end(), printElement);

    std::set<int>::iterator it = numbers.begin();

    // iterate through the set and erase all even numbers
    for (; it != numbers.end(); ++it) {
        int n = *it; …
Run Code Online (Sandbox Code Playgroud)

c++ iterator std set c++-standard-library

140
推荐指数
4
解决办法
9万
查看次数

`new int;` 中的 `new` 是否被视为运算符?

new int;诸如 in 之类的表达式int * x = new int;是一个新表达式。术语“新运算符”似乎可以与“新表达式”互换使用,例如在这个问题中:“新运算符”和“运算符新”之间的区别?

new在 new 表达式中使用的关键字是运算符是否正确?为什么或者为什么不?

如果不是,是否还有另一个理由将新表达式称为“新运算符”?

我无法找到构成运算符的权威定义。

我已经理解为对象分配内存的运算符 new和最终可能调用operator new.

c++ language-lawyer

84
推荐指数
6
解决办法
7616
查看次数

转发声明一个STL容器?

是否可以在头文件中转发声明STL容器?例如,请使用以下代码:

#include <vector>

class Foo
{
private:
    std::vector<int> container_;
    ...
};
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这样的事情:

namespace std
{
    template <typename T> class vector;
}

class Foo
{
private:
    std::vector<int> container_;
    ...
};
Run Code Online (Sandbox Code Playgroud)

可以这样做吗?

c++ header c++-standard-library

47
推荐指数
3
解决办法
2万
查看次数

C++ STL向量与现实世界中的数组

我是C++的新手.我正在阅读迈克尔道森的"通过游戏编程开始C++".但是,我对编程并不陌生.我刚刚完成了一个处理向量的章节,所以我对它们在现实世界中的使用有疑问(我是一名计算机科学专业的学生,​​所以我还没有太多真实的经验).

作者在每章末尾都有一个Q/A,其中一个是:

问:我应该何时使用向量而不是数组?

答:差不多总是如此.向量是高效和灵活的.它们确实比阵列需要更多的内存,但这种权衡几乎总是值得的.

你们有什么感想?我记得在Java书中学习过向量,但是在我的Comp totro中我们根本没有介绍它们.科学.上课,也不是我在大学的数据结构课.我也从未见过它们用于任何编程任务(Java和C).虽然我知道学校代码和现实世界的代码可能会有很大不同,但这让我觉得它们并没有被大量使用.

我不需要被告知两个数据结构之间的差异; 我非常了解他们.我想知道的是,如果作者在他的Q/A中给出了很好的建议,或者他只是想让初学者程序员免于破坏管理固定大小数据结构的复杂性.另外,不管你怎么想作者的意见,你怎么在现实世界往往?

谢谢,

杰拉德

c++ arrays vector c++-standard-library

21
推荐指数
4
解决办法
2万
查看次数

当基类'member'的析构函数具有非空noexcept说明符和body时,析构函数上的C2694

我遇到编译器错误,我无法解释,也无法在线查找有关它的信息.我最近noexcept在包装类的析构函数中添加了一个说明符,现在从使用这个包装器的类继承的大量类无法编译.我已经尝试使用GCC 4.9而没有编译器错误.

我正在使用Visual Studio Professional 2015版本14.0.25431.01 Update 3

请考虑以下最小化代码来重现问题:

#include <type_traits>

template<class T>
struct member
{
    ~member() noexcept(std::is_nothrow_destructible<T>::value) {};
};

struct parent
{ 
    virtual ~parent() noexcept = default;
};


struct derived : public parent
{
    member<int> x;
};
Run Code Online (Sandbox Code Playgroud)

该代码段产生以下错误消息:

1>c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(19): error C2694: 'derived::~derived(void) noexcept(<expr>)': overriding virtual function has less restrictive exception specification than base class virtual member function 'parent::~parent(void) noexcept'
1>  c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(19): note: compiler has generated 'derived::~derived' here
1>  c:\users\fandrieux\workspace\tmp\dtor_noexcept\main.cpp(12): note: see declaration of 'parent::~parent'
Run Code Online (Sandbox Code Playgroud)

我觉得有趣的是,如果你通过更换成员的析构函数体编译器错误消失= default …

c++ visual-studio visual-studio-2015

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

对象生命周期结束和它何时不复存在之间有什么关系?

在下面的简短示例中,关于指针f指向或用于在从 返回之前指向的对象可以说些什么main

#include <vector>

struct foo {
    std::vector<int> m;
};

int main()
{
    auto f = new foo;
    f->~foo();
}
Run Code Online (Sandbox Code Playgroud)

我相信,不再是一个对象foo,其中f用于点。我收到了很多评论,说这可能不正确,而且可能有一个对象foo处于销毁、死亡或其他无效状态。

对于显式销毁但其存储仍然有效的对象的存在,语言标准有什么说法?

换句话说,是否可以合理地说仍然存在一个f超出其生命周期的对象?有没有一个对象不在它的生命周期中,没有开始构造并且没有被破坏?


编辑 :

很明显,一个对象可以在它不在其生命周期内时存在。在构造和销毁过程中,有一个对象,它的生命周期尚未开始或已经结束。来自https://timsong-cpp.github.io/cppwp/intro.object#1

[...] 一个对象在其构建期间 ([class.cdtor])、整个生命周期和销毁期间 ([class.cdtor]) 占用一个存储区域。[...]

但是在f->~foo();f(我们称之为o)指向的对象没有被构造之后,它不在它的生命周期中,也没有被破坏。我对本节的阅读是o不能再占用存储空间,因为它不在任何列举的情况下。似乎这意味着o不再有并且不再有指向的指针o。相反,如果您有一个指向o该指针的指针,那么该指针将指向o无法占用的存储空间。


编辑2:

如果不再有对象,那么还有什么样的价值foo?似乎它可以拥有的唯一合理的可能值是指向对象的指针,这与该语句相矛盾。看到这个问题

c++ lifetime object-lifetime language-lawyer

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

使用VC++的__assume可以带来可衡量的性能提升吗?

使用VC++可以获得可衡量的性能提升__assume吗?如果是这样,请在答案中张贴带代码和基准的证明.

关于__assume的稀疏MSDN文章:http://msdn.microsoft.com/en-us/library/1b3fsfxw( v = vs.100).aspx

文章提到在是利用__assume(0)使switch通过语句更快__assume(0)荷兰国际集团的default情况.我通过__assume(0)这种方式测量的性能没有增加:

void NoAssumeSwitchStatement(int i)
{
    switch (i)
    {
    case 0:
        vector<int>();
        break;
    case 1:
        vector<int>();
        break;
    default:
        break;
    }
}

void AssumeSwitchStatement(int i)
{
    switch (i)
    {
    case 0:
        vector<int>();
        break;
    case 1:
        vector<int>();
        break;
    default:
        __assume(0);
    }
}

int main(int argc, char* argv[])
{
    const int Iterations = 1000000;
    LARGE_INTEGER start, middle, end;
    QueryPerformanceCounter(&start);
    for (int i = …
Run Code Online (Sandbox Code Playgroud)

c++ performance compiler-optimization visual-c++

10
推荐指数
2
解决办法
2018
查看次数

C ++“#include”输出说明

试图了解其#include工作原理。我正在阅读,在进行过程中,它只是将自己替换为引用文件的内容。

为了验证,我创建了两个文件。名为的文件仅包含otherfile字符串1234,而test.cpp包含的文件

#include otherfile
abcd
Run Code Online (Sandbox Code Playgroud)

我运行g++ -E test.cpp,我得到的输出是

# 1 "test.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 373 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "test.cpp" 2
# 1 "./wtf" 1
1234
# 2 "test.cpp" 2
abcd
Run Code Online (Sandbox Code Playgroud)

其余的行是从哪里来的,它们是什么意思?

c++ gcc g++

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

类函数宏的参数中是否允许使用预处理器指令?

这个问题涉及在类似函数的宏参数中使用预处理器指令的合法性。

考虑以下代码。#ifdef用于内部MY_MACRO参数:

#include <iostream>

// Macro to print a message along with the line number the macro appears at
#define MY_MACRO( msg ) { std::cerr << "Line " << __LINE__ << "\t- "<< msg << '\n'; }

int main()
{
    // Print the current build configuration
    MY_MACRO(
#ifdef NDEBUG // <-- preprocessor directive in macro argument
        "Release"
#else
        "Debug"
#endif
    )
}
Run Code Online (Sandbox Code Playgroud)

gcc 12 可以,msvc 19 不允许: https: //godbolt.org/z/G8j4aTG6j

标准对此有何规定?

c++ language-lawyer c-preprocessor

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

从全局对象的构造函数调用时的std :: atexit排序

cppreference说std::atexit:

这些函数可以与具有静态存储持续时间的对象的销毁同时被调用,并且保持如果在B的注册之前如果A的注册被排序,则在调用之前对B的调用进行排序的保证. A,同样适用于静态对象构造函数和对atexit的调用之间的顺序

我理解这一段意味着,如果std::atexit在静态初始化期间调用,则在静态对象的销毁过程中,在静态对象被破坏之前调用已注册的函数,该静态对象std::atexit在调用注册函数时被最后初始化.我还解释"可以同时调用"意味着调用可以发生在静态对象析构之间,而不是对单词的多线程解释.

我想知道的是,当初始化开始或完成时,对象是否被视为已初始化(在此排序的上下文中).我写了一个简短的测试来测试这个:

#include <cstdlib>
#include <iostream>

struct foo
{
    foo() 
    {
        std::cout << "ctor\n";
        std::atexit([]() { std::cout << "atexit\n"; });
    }
    ~foo()
    {
        std::cout << "dtor\n";
    }
};

foo my_foo;

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是(http://cpp.sh/3bllu):

ctor
dtor
atexit
Run Code Online (Sandbox Code Playgroud)

这使我相信,my_foo在构建完成之前,不会在这种情况下初始化.换句话说,该函数被认为在my_foo初始化之前已经注册,因此注册函数在my_foo销毁之后执行.

我似乎找不到任何可以保证这种行为的东西,我甚至不完全确定我对引用段落的初步解释是正确的.我描述的行为是我可以依赖的,还是实现定义甚至未定义的行为?

c++ atexit initialization-order static-initialization language-lawyer

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