小编Wal*_*ter的帖子

try-catch-rethrow的代码是否等同于没有try-catch的代码?

在哪种情况下,以下两个代码不相同?

{
  // some code, may throw and/or have side effects
}

try {
  // same code as above
} catch(...) {
  throw;
}
Run Code Online (Sandbox Code Playgroud)

编辑只是为了澄清,我对(i)偏离上述模式(例如catch块中的更多代码)以及(ii)旨在邀请关于try- catchblock 的正确使用的光顾评论感兴趣.

我正在寻找一个参考C++标准的合格答案.这个问题是由干杯和他的评论提出的.- Alf对我的这个答案,说明没有进一步说明上述代码不相同.


编辑他们确实不同.堆栈取消将在后者中完成,但不一定在前者中,取决于是否catch在运行时找到异常处理程序(堆栈上方的某些块).

c++ exception try-catch throw language-lawyer

23
推荐指数
2
解决办法
1339
查看次数

为什么unique_ptr :: operator*()没有安全的替代方案?

std::vector将成员函数at()作为安全替代operator[],以便应用绑定检查并且不会创建悬空引用:

void foo(std::vector<int> const&x)
{
  const auto&a=x[0];     // What if x.empty()? Undefined behavior!
  const auto&a=x.at(0);  // Throws exception if x.empty().
}
Run Code Online (Sandbox Code Playgroud)

但是,std::unique_ptr缺少相应的功能:

void foo(std::unique_ptr<int> const&x)
{
  const auto&a=*x;       // What if bool(x)==false? Undefined behavior!
}
Run Code Online (Sandbox Code Playgroud)

如果std::unique_ptr有这样一个安全的替代方案,那就好了,说成员ref()(和cref())永远不会返回一个悬空引用,而是抛出异常.可能的实施:

template<typename T>
typename add_lvalue_reference<T>::type
unique_ptr<T>::ref() const noexcept(false)
{
  if(bool(*this)==false)
    throw run_time_error("trying to de-refrence null unique_ptr");
  return this->operator*();
}
Run Code Online (Sandbox Code Playgroud)

这个标准没有提供这种东西有什么好的理由吗?

c++ unique-ptr dereference c++11 dangling-pointer

17
推荐指数
2
解决办法
1890
查看次数

为什么std :: vector有两个赋值运算符?

自2011年以来,我们同时拥有复制和移动任务.但是,这个答案非常有说服力地说,对于资源管理类,只需要一个赋值运算符.对于std::vector,例如,这看起来像

vector& vector::operator=(vector other)
{
  swap(other);
  return*this;
}
Run Code Online (Sandbox Code Playgroud)

这里重要的一点是,论证是以价值为基础的.这意味着在输入函数体的时刻,大部分工作已经通过构造来完成other(如果可能的话,通过移动构造函数,否则通过复制构造函数).因此,这会自动正确地实现复制和移动分配.

如果这是正确的,为什么(根据这个文档至少)std::vector 没有以这种方式实现?


编辑以解释这是如何工作的.请考虑other以下示例中的上述代码中发生的情况

void foo(std::vector<bar> &&x)
{
  auto y=x;             // other is copy constructed
  auto z=std::move(x);  // other is move constructed, no copy is ever made.
  // ...
}
Run Code Online (Sandbox Code Playgroud)

c++ vector copy-and-swap c++11

17
推荐指数
2
解决办法
825
查看次数

是否有一个有效的C++ 11程序,其表达式为"C++ 11"?

编程语言C++的名称源自父语言C和++运算符(它应该可以说是++ C),因此,表达式C++可能自然地出现在C++程序中.我想知道你是否可以使用2011标准(没有扩展名)编写有效的C++程序,并且包含C++11 不在引号内和预处理之后的表达式(注意:编辑了要求,另请参阅答案).

很显然,如果你能写之前,2011年的标准与表达一个C++程序C++98或者C++03,那么答案是肯定的小事.但我不认为这是可能的(虽然我不知道).那么,它可以用C++ 11的新军械库来完成吗?

c++ c++11

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

我+ =(i&-i)做什么?它是便携式的吗?

我们i是一个有符号整数类型.考虑

i += (i&-i);
i -= (i&-i);
Run Code Online (Sandbox Code Playgroud)

最初的地方i>0.

  1. 这些怎么办?是否只有使用算术的等效代码?
  2. 这取决于负整数的特定位表示吗?

来源:setter的在线编码拼图代码(没有任何解释/评论).

c++ integer bit-manipulation

16
推荐指数
4
解决办法
2170
查看次数

为什么没有std :: make_function()?

std::function<>几乎任何可调用的东西都是一个有用的包装器,包括自由函数,lambda,仿函数,成员函数,结果std::bind.但是,在创建a时std::function<>,必须明确指定函数签名(取自此处)

struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};

void print_num(int i)
{ std::cout << i << '\n'; }

struct PrintNum {
    void operator()(int i) const
    { std::cout << i << '\n'; }
};

// store a free function
std::function<void(int)> f_display = print_num;

// store a lambda
std::function<void()> f_display_42 = []() { print_num(42); };

// store the result of …
Run Code Online (Sandbox Code Playgroud)

c++ function c++11

15
推荐指数
2
解决办法
2886
查看次数

究竟什么是"尾随参数包"

在解决函数模板重载之间的歧义时,会执行部分排序(有关解释,请参见此处).在那个网站上,我们也了解到了这一点

在平局的情况下,如果一个函数模板具有尾随参数包而另一个没有,则具有省略参数的那个被认为比具有空参数包的那个更专业.

现在,我想知道什么是尾随参数包.如果有的话

template<class ...> struct tuple { /* ... */ };

template<class T, class...Ts> void foo(tuple<T,Ts...>);

template<class T, class...Ts> void bar(T, Ts...);
Run Code Online (Sandbox Code Playgroud)

是和哪个不是为什么?还要注意clang认为

template<class T> void f(tuple<T>);

template<class T, class...Ts> void f(tuple<T,Ts...>);

int main()
{  f(tuple<int>());  }   // ambiguous call?
Run Code Online (Sandbox Code Playgroud)

含糊不清,暗示foo没有尾随参数包.

c++ overloading language-lawyer variadic-templates c++11

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

在C++ 11中使用decltype()时出错(在gcc 4.7.0中创建不透明的错误消息)

使用以下代码(我的原始代码的简化版本)

#include <iostream>
#include <cmath>

template <typename> class A;                  // edit 1 following Mark & Matthieu
template <typename X> class A {
  X a;
  template <typename> friend class A;         // edit 1 following Mark & Matthieu
public:
  A(X x) : a(x) {}
  X get() const { return a; }                // edit 2 to avoid using A<Y>::a
  template <typename Y>
  auto diff(A<Y> const& y) const
    -> decltype(a - y.a)                       // original code causing error with gcc
    -> typename std::common_type<X, Y>::type  // …
Run Code Online (Sandbox Code Playgroud)

c++ decltype auto c++11

14
推荐指数
2
解决办法
946
查看次数

如果T1和T2有,那么std :: pair <T1,T2>是否应该具有普通的默认构造函数?

我遇到了一个问题,因为

 std::is_trivially_default_constructible<std::pair<T1,T2>>::value == false;
Run Code Online (Sandbox Code Playgroud)

即使

 std::is_trivially_default_constructible<T1>::value == true;
 std::is_trivially_default_constructible<T2>::value == true;
Run Code Online (Sandbox Code Playgroud)

我没有找到这个设计的充分理由.如果有的话,拥有std::pair<T1,T2>一个=default构造函数是不合适的?T1T2

有一个简单的工作(比定义我自己更简单pair<>)?

c++ default-constructor language-lawyer c++11

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

如何制作一个简单的C++程序,其中没有刷新std :: cout

为了更好地理解C++中的缓冲流,我想编写一个简单的程序,std::cout在终止之前不刷新缓冲区.由于我已经读取了std::cout在正常终止时刷新,我尝试抛出运行时错误.我也避免使用std::endl,据我所知,强制冲洗.第一次尝试:

//file noflush.cpp
#include <iostream>

int main() {
    std::cout << "Don't write me to the console!";
    throw 0;
}
Run Code Online (Sandbox Code Playgroud)

用g ++编译,从终端调用:

$ ./noflush
libc++abi.dylib: terminating with uncaught exception of type int
Don't write me to the console!Abort trap: 6
Run Code Online (Sandbox Code Playgroud)

即使我强制运行时出错,看起来缓冲区在终止时仍然会被刷新.是否有可能在缓冲区中"绑定"某些数据,使其不被写入设备?

c++ buffer cout stdout stream

13
推荐指数
2
解决办法
1506
查看次数