小编bam*_*s53的帖子

如何拥有"constexpr和运行时"别名

Constexpr对编译优化非常有用.例如...

strlen(char*)
Run Code Online (Sandbox Code Playgroud)

可以使用....预编译

constexpr inline size_t strlen_constexpr(char* baseChar) {
    return (
            ( baseChar[0] == 0 )
            ?(// if {
              0
              )// }
            :(// else {
              strlen_constexpr( baseChar+1 ) + 1 
              )// }
            );
}
Run Code Online (Sandbox Code Playgroud)

这在优化时给它的运行时成本为"0"但是在运行时速度超过10 + x

// Test results ran on a 2010 macbook air
--------- strlen ---------
Time took for 100,000 runs:1054us.
Avg Time took for 1 run: 0.01054us.
--------- strlen_constexpr ---------
Time took for 100,000 runs:19098us.
Avg Time took for 1 run: 0.19098us.
Run Code Online (Sandbox Code Playgroud)

是否有任何现有的宏/模板黑客可以使用单个统一功能.即.

constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ optimization compiler-optimization c++11

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

为什么uniform_int_distribution <uintmax_t>适用于62位数字但不适用于63位或64位数字?

我很难理解为什么这个代码,尝试<random>在C++ 11中使用新的标头,正确地生成随机数[0, 2**62 - 1]而不是[0, 2**63 - 1][0, 2**64 - 1].

#include <iostream>
#include <stdint.h>
#include <random>
#include <functional>
#include <ctime>

static std::mt19937 engine; // Mersenne twister MT19937

void print_n_random_bits (unsigned int n);

int main (void) {
  engine.seed(time(0));
  print_n_random_bits(64);
  print_n_random_bits(63);
  print_n_random_bits(62);
  return 0;
}

void print_n_random_bits (unsigned int n)
{
  uintmax_t max;

  if (n == 8 * sizeof(uintmax_t)) {
    max = 0;
  } else {
    max = 1;
    max <<= n;
  } …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 libc++

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

防止非常量左值解析为右值引用而不是const左值引用

我无法通过const引用重载函数来获取值,或者如果它是rvalue则是rvalue引用.问题是我的非const左值绑定到函数的右值版本.我在VC2010中这样做.

#include <iostream>
#include <vector>

using namespace std;

template <class T>
void foo(const T& t)
{cout << "void foo(const T&)" << endl;}

template <class T>
void foo(T&& t)
{cout << "void foo(T&&)" << endl;}

int main()
{
    vector<int> x;
    foo(x); // void foo(T&&) ?????
    foo(vector<int>()); // void foo(T&&)
}
Run Code Online (Sandbox Code Playgroud)

优先级似乎是推导foo(x)为

foo< vector<int> & >(vector<int>& && t)
Run Code Online (Sandbox Code Playgroud)

代替

foo< vector<int> >(const vector<int>& t)
Run Code Online (Sandbox Code Playgroud)

我尝试用r替换rvalue-reference版本

void foo(typename remove_reference<T>::type&& t)
Run Code Online (Sandbox Code Playgroud)

但这只会导致所有内容都解析为const-lvalue引用版本.

我该如何防止这种行为?为什么这仍然是默认值 - 考虑到允许修改rvalue-references似乎很危险,这给我留下了意外修改的局部变量.

编辑:刚添加了非模板版本的函数,它们按预期工作.将函数设为模板会更改重载决策规则吗?那真是令人沮丧!

void bar(const vector<int>& t)
{cout << "void bar(const …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming rvalue-reference

19
推荐指数
2
解决办法
1902
查看次数

什么是C11中的gets()等价?

来自cplusplus.com

最新版本的C标准(2011年)最终将该功能从其规范中删除

该函数在C++中已弃用(截至2011年标准,遵循C99 + TC3).

我只想知道gets()C11标准的替代方案是什么?

c c11

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

初始化表达式的每种方式的优缺点是什么?

这是受到Andrei Alexandrescu的一篇文章的启发.

使用以下方法初始化表达式的专家和概念是什么?我什么时候应该更喜欢一个?

auto v = expr;
T v = expr;
auto v(expr);
T v(expr);
auto v { expr }; 
T v {expr};
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

17
推荐指数
3
解决办法
1347
查看次数

什么是完美转发设置器的正确`enable_if`约束?

Herb Sutter 回归基础!CppCon 上的现代C++演示要点讨论了传递参数的不同选项,并将其性能与写作/教学的简易性进行了比较."高级"选项(在所有测试的案例中提供最佳性能,但对大多数开发人员来说难以编写)是完美转发,给出了示例(PDF,第28页):

class employee {
    std::string name_;

public:
    template <class String,
              class = std::enable_if_t<!std::is_same<std::decay_t<String>,
                                                     std::string>::value>>
    void set_name(String &&name) noexcept(
      std::is_nothrow_assignable<std::string &, String>::value) {
        name_ = std::forward<String>(name);
    }
};
Run Code Online (Sandbox Code Playgroud)

该示例使用带转发引用的模板函数,模板参数String使用约束enable_if.然而,约束似乎是不正确的:似乎只有在String类型不是a 时才使用此方法std::string,这没有任何意义.这将意味着该std::string成员可以使用设置什么,但一个std::string值.

using namespace std::string_literals;

employee e;
e.set_name("Bob"s); // error
Run Code Online (Sandbox Code Playgroud)

我考虑的一个解释是,有一个简单的拼写错误,而且约束的目的是std::is_same<std::decay_t<String>, std::string>::value代替!std::is_same<std::decay_t<String>, std::string>::value.然而,这意味着setter不能使用,例如,const char *它显然是打算使用这种类型,因为这是在演示文稿中测试的案例之一.

在我看来,正确的约束更像是:

template <class String,
          class = std::enable_if_t<std::is_assignable<decltype((name_)),
                                                      String>::value>>
void set_name(String &&name) …
Run Code Online (Sandbox Code Playgroud)

c++ enable-if perfect-forwarding c++11 forwarding-reference

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

为什么chrono有自己的命名空间?

到目前为止,我在C++标准库中看到的所有其他内容都在std命名空间中.如果我使用的东西std::chrono我通常超过我的每行限制80个字符 - 这不是一个问题,只是不方便.

所以这里我的简单问题是:为什么chrono头有自己的命名空间?

c++ c++11 c++-chrono

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

用c ++编写的程序可以在任何地方运行吗?

我知道要在Windows上运行c ++,你需要专门为Windows编译,同样适用于Linux和...

但是,例如,如果我正在编译用本机c ++编写的Windows程序,我可以在新安装的Windows PC上运行它吗?我的意思是,在没有下载可视化c ++运行时库等的情况下,我可以编译它,比方说,在我的计算机上重新安装Windows,并在不安装任何其他东西的情况下运行它?

(上面的问题使用Windows作为示例,但同样的事情可以在新安装的Linux发行版上完成?例如Ubuntu)在此先感谢.

c++

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

可以使用typedef名称来声明或定义构造函数吗?

Standardese:

[class.ctor] 12.1/1说

特殊的声明符语法用于声明或定义构造函数.语法使用:

    - 一个可选的decl-specifier-seq,其中每个decl-specifier都是一个函数说明符constexpr,

    - 构造函数的类名,和

    - 参数列表

以该顺序.

[class.name] 9.1/4说

命名类类型或其cv限定版本的typedef-name(7.1.3)也是类名.如果在需要类名的地方使用命名cv限定类类型的typedef-name,则忽略cv限定符.甲的typedef名称不应被用作 标识符在一个类头.

另外[expr.prim.general] 5.1.1/8说

在使用class-name :: class-name且两个类名引用同一个类的情况下,此表示法命名构造函数(12.1).


应用:

在我看来,应该允许使用typedef名称来声明构造函数(尽管事实上12.1/1不使用斜体类名).

例如,给定:

struct Foo;
typedef Foo Bar;
Run Code Online (Sandbox Code Playgroud)

然后

struct Foo { Bar() {} }; // defines Foo's constructor. - 1
Run Code Online (Sandbox Code Playgroud)

或者代之以

struct Foo;
struct Foo { Foo() };
typedef Foo Bar;
Run Code Online (Sandbox Code Playgroud)

然后

Foo::Bar() {}; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

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

使用RAII嵌套异常

所以在C++中嵌套异常的方法std::nested_exception是:

void foo() {
  try {
    // code that might throw
    std::ifstream file("nonexistent.file");
    file.exceptions(std::ios_base::failbit);
  }

  catch(...) {
    std::throw_with_nested(std::runtime_error("foo failed"));
  }
}
Run Code Online (Sandbox Code Playgroud)

但是这种技术在每个级别使用显式的try/catch块,希望嵌套异常,这至少可以说是丑陋的.

Jon Kalb扩展为"责任获取是初始化"的RAII,是处理异常而不是使用显式try/catch块的更清晰的方法.使用RAII,显式try/catch块主要仅用于最终处理异常,例如,为了向用户显示错误消息.

查看上面的代码,在我看来,输入foo()可以被视为有责任报告任何异常,std::runtime_error("foo failed")并将细节嵌套在嵌套异常中.如果我们可以使用RAII来获得这个责任,那么代码看起来会更清晰:

void foo() {
  Throw_with_nested on_error("foo failed");

  // code that might throw
  std::ifstream file("nonexistent.file");
  file.exceptions(std::ios_base::failbit);
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在这里使用RAII语法来替换显式的try/catch块?


为此,我们需要一种类型,当它的析构函数被调用时,检查析构函数调用是否是由异常引起的,如果是,则嵌套该异常,并抛出新的嵌套异常,以便正常地展开.这可能看起来像:

struct Throw_with_nested {
  const char *msg;

  Throw_with_nested(const char *error_message) : msg(error_message) {}

  ~Throw_with_nested() {
    if (std::uncaught_exception()) {
      std::throw_with_nested(std::runtime_error(msg));
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

但是,std::throw_with_nested()要求"当前处理的异常"处于活动状态,这意味着除了catch块的上下文之外它不起作用.所以我们需要这样的东西:

  ~Throw_with_nested() {
    if (std::uncaught_exception()) {
      try …
Run Code Online (Sandbox Code Playgroud)

c++ exception raii nested-exceptions c++11

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