相关疑难解决方法(0)

C++ 17引入了哪些评估顺序保证?

在典型的C++代码中,C++ 17评估顺序保证(P0145)投票的含义是什么?

对于像这样的事情,它有什么变化

i=1;
f(i++, i)
Run Code Online (Sandbox Code Playgroud)

std::cout << f() << f() << f() ;
Run Code Online (Sandbox Code Playgroud)

要么

f(g(),h(),j());
Run Code Online (Sandbox Code Playgroud)

c++ operator-precedence c++17

77
推荐指数
2
解决办法
7130
查看次数

v != std::exchange(v, previous(v)) 中的求值顺序

我一直在寻找更多适合的习语std::exchange

今天我发现自己在一个答案中写下了这个:

do {
    path.push_front(v);
} while (v != std::exchange(v, pmap[v]));
Run Code Online (Sandbox Code Playgroud)

我比说更喜欢它

do {
    path.push_front(v);
    if (v == pmap[v])
        break;
    v= pmap[v];
} while (true);
Run Code Online (Sandbox Code Playgroud)

希望有明显的原因。

然而,我对标准语言并不热衷,我不禁担心这并lhs != rhs不能保证右侧表达式在左侧表达式之前没有被完全求值。这将使其成为同义反复的比较 - 根据定义将返回true.

然而,代码确实运行正确,显然lhs首先进行评估。

有人知道吗

  • 标准是否保证该评估顺序
  • 如果最近的标准发生了变化,哪个标准版本首先指定了它?

附言。f(a,b)我意识到这是where fis的一个特例operator!=。我尝试使用此处找到的信息回答我自己的查询,但迄今为止未能得出结论:

c++ sequence-points language-lawyer

37
推荐指数
2
解决办法
2238
查看次数

功能参数评估顺序

C/C++,是否有一个固定的顺序来评估函数的参数?我的意思是,标准说什么?难道left-to-right还是right-to-left?我从书中得到了令人困惑的信息.

是否有必要function call使用stack only.什么是C/C++标准,说这个?

c c++

19
推荐指数
3
解决办法
7667
查看次数

编译器是否允许在不同的函数参数中交织子表达式的评估?

我想知道以下情况:

void f(int a, int b) { }

int a(int x) { std::cout << "func a" << std::endl; return 1; }
int b(int x) { std::cout << "func b" << std::endl; return 2; }

int x() { std::cout << "func x" << std::endl; return 3; }
int y() { std::cout << "func y" << std::endl; return 4; }

f(a(x()), b(y()));
Run Code Online (Sandbox Code Playgroud)

在阅读http://en.cppreference.com/w/cpp/language/eval_order后,我仍然难以理解以下评估顺序是否可行:

x()- > y()- > a()- >b()

或者标准保证a(x())并且b(y())将被评估为单位,可以这么说.

换句话说,是否有可能打印出来

func …
Run Code Online (Sandbox Code Playgroud)

c++

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

std :: make_unique <T> vs reset(新T)

我想问一个关于构造函数中的内存泄漏的问题.我们来考虑一个课程:

 class Foo
 {
   public:
      Foo(){ throw 500;} 
 };
Run Code Online (Sandbox Code Playgroud)

有什么区别

std::unique_ptr<Foo> l_ptr = std::make_unique<Foo>();
Run Code Online (Sandbox Code Playgroud)

std::unique_ptr<Foo> l_ptr;
l_ptr.reset(new Foo());
Run Code Online (Sandbox Code Playgroud)

在我看来,make_unique的解决方案应该保护我免受内存泄漏,但在这两种情况下我得到了相同的valgrind结果:

$ valgrind --leak-check=full ./a.out
==17611== Memcheck, a memory error detector
==17611== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17611== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17611== Command: ./a.out
==17611== 
terminate called after throwing an instance of 'int'
==17611== 
==17611== Process terminating with default action of signal 6 (SIGABRT)
==17611==    at 0x5407418: raise …
Run Code Online (Sandbox Code Playgroud)

c++ memory-leaks smart-pointers unique-ptr c++11

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

如何正确转发unique_ptr?

通常什么是转发std :: unique_ptr的正确方法?

下面的代码使用std::move,我认为这是考虑的做法,但它与clang崩溃.

class C {
   int x;
}

unique_ptr<C> transform1(unique_ptr<C> p) {
    return transform2(move(p), p->x); // <--- Oops! could access p after move construction takes place, compiler-dependant
}

unique_ptr<C> transform2(unique_ptr<C> p, int val) {
    p->x *= val;
    return p;
}
Run Code Online (Sandbox Code Playgroud)

是否有更强大的约定,而不仅仅是确保p在将所有权转移到下一个功能之前获得所需的一切std::move?在我看来,move在一个对象上使用并访问它以向同一函数调用提供参数可能是一个常见的错误.

c++ move unique-ptr c++11

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

使用后增量构造带有变量的 std::pair 整数

我尝试构造整数对,其中第二个整数大于第一个整数1

1 2
2 3
3 4
Run Code Online (Sandbox Code Playgroud)

std::make_pair像这样使用两者和构造函数:

std::make_pair(n, n++);
Run Code Online (Sandbox Code Playgroud)

但是,这会导致对相反:

2 1
3 2
4 3
Run Code Online (Sandbox Code Playgroud)

如果我将后增量放在第一个参数上或(n+1)改为使用,我会得到所需的结果。

为什么会这样?

c++ function function-parameter post-increment std-pair

8
推荐指数
2
解决办法
120
查看次数

令人不安的评估顺序

当我使用我最喜欢的容器时,我倾向于连锁操作.例如,在众所周知的Erase-remove成语中:

v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );
Run Code Online (Sandbox Code Playgroud)

根据我所知的评估顺序,v.end()(在rhs上)可能会调用之前进行评估std::remove_if.这不是问题,因为std::remove*只是在不改变其结束迭代器的情况下对矢量进行洗牌.

但它可能导致非常令人惊讶的结构,例如(演示):

#include <iostream>

struct Data
{
    int v;
    int value() const { return v; }
};

auto inc(Data& data)           { return ++data.v; }
void print_rhs(int, int value) { std::cout << value << '\n'; }

int main()
{
    Data data{0};
    print_rhs(inc(data), data.value()); // might print 0
}
Run Code Online (Sandbox Code Playgroud)

这是令人惊讶的,因为print_rhs被叫之后 inc被称为; 这意味着data.v1print_rhs …

c++ expression-evaluation

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

函数参数评估顺序与Lambda捕获评估顺序

似乎函数参数评估的顺序以及lambda捕获初始化器的顺序都未被 C++标准指定.

(参见http://en.cppreference.com/w/cpp/language/lambda以及C++函数参数中的评估顺序)

由于它可能与移动语义相互作用,这引起了一些关注.

假设我有类型的对象,T可能有复制或移动构造函数抛出.然后假设我有一个只移动的对象,比如std::promise.考虑以下情况:

T value; // some type that potentially throws when moved or copied
promise<U> pr; // a promise whose result is some type U
future<U> fut = pr.get_future(); 

std::thread(
  [v = std::move(value), pr = std::move(pr)]() {
    try {
      // do some stuff

      pr.set_value(/* whatever */);
    }
    catch (...) { pr.set_exception(std::current_exception()); }
  }
).detach();

// return the future
Run Code Online (Sandbox Code Playgroud)

现在,我们有一个在其中执行的try/catch块std::thread …

c++ move-semantics c++11 c++14

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

调用约定和评估顺序

我知道C++没有指定参数传递给函数的顺序.但是如果我们编写以下代码:

void __cdecl func(int a, int b, int c)
{
       printf("%d,%d,%d", a,b,c);
}
int main()
{
   int i=10;
   func(++i, i, ++i);
}
Run Code Online (Sandbox Code Playgroud)

我们能否可靠地说输出是12,11,11因为__cdecl确保参数传递顺序是从右到左?

c++ arguments function

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