动机:我之所以考虑是因为我的天才项目经理认为提升是另一种依赖,而且它很可怕,因为"你依赖它"(我试着解释提升的质量,然后放弃一段时间后:(我想做的更小的原因是我想学习c ++ 11的功能,因为人们会开始在其中编写代码.所以:
#include<thread> #include<mutex>
和boost等效?PS我使用GCC所以标题就在那里.
看着一些代码,我偶然发现:
throw /*-->*/new std::exception ("//...
Run Code Online (Sandbox Code Playgroud)
我一直认为你不需要/你不应该new
在这里使用.
什么是正确的方法,都可以,如果有的话有什么区别吗?
BTW从我所看到的同时"使用PowerShell提升库"的"grepping"永远不会使用throw new
.
PS我也发现了一些使用的CLI代码throw gcnew
.这可以吗?
c ++ 11有可能获得当前的线程ID,但它不能转换为整数类型:
cout<<std::this_thread::get_id()<<endl;
Run Code Online (Sandbox Code Playgroud)
输出:139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
Run Code Online (Sandbox Code Playgroud)
错误:从类型'std :: thread :: id'到类型'uint64_t'的无效强制转换与其他类型相同:从类型'std :: thread :: id'到类型'uint32_t'的无效强制转换
我真的不想做指针转换来获取整数线程ID.是否有一些合理的方法(标准因为我希望它是便携式的)来做到这一点?
既然C++ 11有多线程,我想知道在不使用互斥锁的情况下实现延迟初始化单例的正确方法是什么(出于性能原因).我想出了这个,但是我并不擅长编写无锁代码,所以我正在寻找更好的解决方案.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
# include <atomic>
# include <thread>
# include <string>
# include <iostream>
using namespace std;
class Singleton
{
public:
Singleton()
{
}
static bool isInitialized()
{
return (flag==2);
}
static bool initizalize(const string& name_)
{
if (flag==2)
return false;// already initialized
if (flag==1)
return false;//somebody else is initializing
if (flag==0)
{
int exp=0;
int desr=1;
//bool atomic_compare_exchange_strong(std::atomic<T>* obj, T* exp, T desr)
bool willInitialize=std::atomic_compare_exchange_strong(&flag, &exp, desr); …
Run Code Online (Sandbox Code Playgroud) 我查看了一些丑陋的代码(在迭代时修改了基础序列),并探索了基于范围的for
循环的定义,我去了cppreference。
在那里,我注意到了一些奇怪的事情:
基于范围的for
循环在C ++ 17中已更改,但我看不到更改的原因,并且代码对我来说看起来相同(只是“重构”)。因此,旧的是:
{
auto && __range = range_expression;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)
新的是
{
auto && __range = range_expression;
auto __begin = begin_expr;
auto __end = end_expr;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)
为什么要进行此更改,并且它会使任何合法的C ++ 14程序在C ++ 17中表现出未定义的行为(UB)?
您可能知道,C++ 11引入了constexpr
关键字.
C++ 11引入了关键字constexpr,它允许用户保证函数或对象构造函数是编译时常量.[...]这允许编译器理解并验证[函数名称]是编译时常量.
我的问题是为什么对可以声明的函数的形式有严格的限制.我理解保证功能是纯粹的愿望,但考虑到这一点:
在函数上使用constexpr会对函数的作用施加一些限制.首先,该函数必须具有非void返回类型.其次,函数体不能声明变量或定义新类型.第三,正文可能只包含声明,空语句和单个return语句.必须存在参数值,以便在参数替换后,return语句中的表达式生成常量表达式.
这意味着这个纯函数是非法的:
constexpr int maybeInCppC1Y(int a, int b)
{
if (a>0)
return a+b;
else
return a-b;
//can be written as return (a>0) ? (a+b):(a-b); but that isnt the point
}
Run Code Online (Sandbox Code Playgroud)
你也不能定义局部变量... :(所以我想知道这是一个设计决定,还是编译器吮吸来证明功能a是纯粹的?
我见过有些人讨厌recursive_mutex
:
http://www.zaval.org/resources/library/butenhof1.html
但是在考虑如何实现一个线程安全的类(互斥保护)时,我觉得很难证明每个应该受互斥保护的方法都是互斥保护的,并且互斥锁最多被锁定一次.
因此,对于面向对象的设计,应该std::recursive_mutex
是默认的并且std::mutex
在一般情况下被视为性能优化,除非它仅在一个地方使用(仅保护一个资源)?
为了说清楚,我说的是一个私人非静态互斥体.因此每个类实例只有一个互斥锁.
在每个公共方法的开头:
{
std::scoped_lock<std::recursive_mutex> sl;
Run Code Online (Sandbox Code Playgroud) 在查看Clang和g ++ C++ 11实现状态时,我注意到一些奇怪的东西:
它们支持C++ 11原子,但它们不支持C++ 11内存模型.
我的印象是你必须有C++ 11内存模型才能使用原子.那么对原子和内存模型的支持究竟有什么区别呢?
缺乏内存模型支持意味着合法的C++ 11程序使用std::atomic<T>
不一致的seq吗?
参考:
http://clang.llvm.org/cxx_status.html
http://gcc.gnu.org/gcc-4.7/cxx0x_status.html
我有一个愚蠢的问题.我尝试切换到c ++ 11标头,其中一个是chrono.但我的问题是我无法控制时间操作的结果.例如:
auto t=std::chrono::high_resolution_clock::now();
cout<<t.time_since_epoch();
Run Code Online (Sandbox Code Playgroud)
得到:
初始化
‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = std::chrono::duration<long int, std::ratio<1l, 1000000l> >]’
... /usr/include/c++/4.6/ostream的 参数1
cout<<(uint64_t)t.time_since_epoch();
Run Code Online (Sandbox Code Playgroud)
给出无效的演员
考虑这个代码:
#include <iostream>
template<typename A>
struct S{
S(const A& a){
std::cout << "L\n";
}
S(A&& a){
std::cout << "R\n";
}
};
S<int> f1(){
int a = 1;
return {a};
}
S<int> f2(){
int a = 1;
return a;
}
S<int> f3(){
int a = 1;
return {std::move(a)};
}
int main()
{
f1();
f2();
f3();
}
Run Code Online (Sandbox Code Playgroud)
输出是
左
右
右
您可能知道 C++ 在返回值中隐式移动(在 f2 中)。当我们在初始值设定项列表中手动执行时,它可以工作(f3),但它不会在 f1 中由 C++ 自动完成。
这是否有充分的理由为什么这不起作用,或者只是被认为不够重要而无法由标准指定的极端情况?
PS 我知道编译器可以(有时必须)执行 RVO,但我不明白这如何解释输出。