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) 我很难理解为什么这个代码,尝试<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) 我无法通过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标准(2011年)最终将该功能从其规范中删除
该函数在C++中已弃用(截至2011年标准,遵循C99 + TC3).
我只想知道gets()
C11标准的替代方案是什么?
这是受到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) 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++标准库中看到的所有其他内容都在std
命名空间中.如果我使用的东西std::chrono
我通常超过我的每行限制80个字符 - 这不是一个问题,只是不方便.
所以这里我的简单问题是:为什么chrono头有自己的命名空间?
我知道要在Windows上运行c ++,你需要专门为Windows编译,同样适用于Linux和...
但是,例如,如果我正在编译用本机c ++编写的Windows程序,我可以在新安装的Windows PC上运行它吗?我的意思是,在没有下载可视化c ++运行时库等的情况下,我可以编译它,比方说,在我的计算机上重新安装Windows,并在不安装任何其他东西的情况下运行它?
(上面的问题使用Windows作为示例,但同样的事情可以在新安装的Linux发行版上完成?例如Ubuntu)在此先感谢.
[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++中嵌套异常的方法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)