我试着寻找这方面的细节,我甚至阅读了关于互斥和原子的标准......但我仍然无法理解C++ 11内存模型的可见性保证.据我所知,互斥BESIDE互斥的一个非常重要的特点是确保可见性.Aka每次只有一个线程增加计数器是不够的,重要的是线程增加了最后使用互斥锁的线程所存储的计数器(我真的不知道为什么人们在讨论时不再提这个互斥,也许我有坏老师:)).所以从我可以告诉原子并不强制立即可见性:(来自维护boost :: thread并已实现c ++ 11线程和互斥库的人):
具有memory_order_seq_cst的fence不会强制立即查看其他线程(并且MFENCE指令也不会).C++ 0x内存排序约束只是---排序约束.memory_order_seq_cst操作形成一个总顺序,但对该顺序没有任何限制,除了它必须由所有线程达成一致,并且它不得违反其他排序约束.特别是,如果线程按照与约束一致的顺序看到值,则线程可能会在一段时间内继续看到"陈旧"值.
而且我很好.但问题在于我无法理解C++ 11关于原子的构造是"全局的",而且只能确保原子变量的一致性.特别是我了解以下内存排序中的哪些(如果有的话)保证在加载和存储之前和之后将有一个内存栅栏:http: //www.stdthread.co.uk/doc/headers/atomic/memory_order. HTML
从我可以告诉std :: memory_order_seq_cst插入mem屏障,而其他只强制执行某些内存位置上的操作的顺序.
所以有人可以清楚这一点,我认为很多人会使用std :: atomic制作可怕的错误,如果他们不使用默认值(例如std :: memory_order_seq_cst内存排序),
那么就是2.如果我是对的,那就意味着第二行是此代码中的冗余:
atomicVar.store(42);
std::atomic_thread_fence(std::memory_order_seq_cst);
Run Code Online (Sandbox Code Playgroud)
3. std :: atomic_thread_fences在某种意义上与互斥量具有相同的要求,为了确保非原子变量的seq一致性,必须执行std :: atomic_thread_fence(std :: memory_order_seq_cst); 在load和std :: atomic_thread_fence(std :: memory_order_seq_cst)之前;
经过商店?
是的
{
regularSum+=atomicVar.load();
regularVar1++;
regularVar2++;
}
//...
{
regularVar1++;
regularVar2++;
atomicVar.store(74656);
}
Run Code Online (Sandbox Code Playgroud)
相当于
std::mutex mtx;
{
std::unique_lock<std::mutex> ul(mtx);
sum+=nowRegularVar;
regularVar++;
regularVar2++;
}
//..
{
std::unique_lock<std::mutex> ul(mtx);
regularVar1++;
regularVar2++;
nowRegularVar=(74656);
}
Run Code Online (Sandbox Code Playgroud)
我想不是,但我想确定.
编辑:5.可以断言?
只存在两个线程.
atomic<int*> p=nullptr;
Run Code Online (Sandbox Code Playgroud)
第一个线程写
{
nonatomic_p=(int*) malloc(16*1024*sizeof(int));
for(int i=0;i<16*1024;++i) …
Run Code Online (Sandbox Code Playgroud) Clang 和 GCC不同意接受此代码。
什么是标准要求的行为?
#include <utility>
#include <iostream>
#include <vector>
int main()
{
std::vector pairs = {std::pair{1,11},{2,22}, {3,33}};
for (const auto& p: pairs) {
std::cout << p.second << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:我知道这是 C++,所以标准可能是模糊的,但我认为一种行为是正确的。
我想知道是否有可能在编译时检查两种类型是否相同.我想出的是(idk如果它有效,因为它感觉hackish和IDK标准好,所以IDK在测试时要寻找什么).
#include <boost/strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(double, cm);
BOOST_STRONG_TYPEDEF(double, inch);
template<typename T, typename U>
static constexpr void __help()
{
}
template<typename T, typename U>
class AreSameType
{
public:
constexpr operator bool()
{
return &__help<T,U> == &__help<U,T>;
};
};
Run Code Online (Sandbox Code Playgroud)
用法:
int main()
{
static_assert(AreSameType<double,float>()== false, "oh noes1");
static_assert(AreSameType<double,double>()== true, "oh noes2");
static_assert(AreSameType<int*,double*>()== false, "oh noes3");
static_assert(AreSameType<double*,double>()== false, "oh noes4");
static_assert(AreSameType<const double,double>()== false, "oh noes5");
static_assert(AreSameType<inch,cm>()== true, "oh expected"); //fires
}
Run Code Online (Sandbox Code Playgroud)
所以
1)有更好的方法吗?
2)这个功能黑客的地址保证按标准工作(我打赌不会:))?
在尝试使用C++ 17折叠表达式时,我试图实现max sizeof
,其中结果是最多sizeof
的类型.我有一个使用变量和lambda的丑陋折叠版本,但我无法想到使用折叠表达式并std::max()
获得相同结果的方法.
这是我的折叠版本:
template<typename... T>
constexpr size_t max_sizeof(){
size_t max=0;
auto update_max = [&max](const size_t& size) {if (max<size) max=size; };
(update_max(sizeof (T)), ...);
return max;
}
static_assert(max_sizeof<int, char, double, short>() == 8);
static_assert(max_sizeof<char, float>() == sizeof(float));
static_assert(max_sizeof<int, char>() == 4);
Run Code Online (Sandbox Code Playgroud)
我想用折叠表达式编写等效函数std::max()
.例如,对于3个元素,它应该扩展为
return std::max(sizeof (A), std::max(sizeof(B), sizeof (C)));
Run Code Online (Sandbox Code Playgroud)
有可能吗?
您可能知道C++ 11有noexcept关键字.现在丑陋的部分是这样的:
请注意,函数的noexcept规范不是编译时检查; 它只是程序员通知编译器函数是否应抛出异常的方法.
http://en.cppreference.com/w/cpp/language/noexcept_spec
那么这是委员会部分的设计失败还是他们只是把它作为编译作者的练习:)从某种意义上来说,正常的编译器会强制执行它,坏的仍然可以兼容?
顺便说一句,如果你问为什么没有第三个选项(也就是说不能做),原因是我可以很容易地想到一个(慢)方法来检查函数是否可以抛出.如果你将输入限制为5和7(也就是我保证文件不会包含5和7旁边的任何内容),问题就会失败,并且只有当你给它33时它才会抛出,但这不是一个现实的问题恕我直言.
我想知道是否有一个VS工具可以显示给定C++函数的调用图(即列出所有可能的执行路径的图表).在仅在少数几个地方调用函数的情况下,它将有助于导航大代码库.
对于经常被称为函数,printf
它可以简单地说:
选择太多......
再一次,我想制作这样的工具真的不容易,所以我想知道它是否存在,但你知道它似乎可以这样做,所以你永远不会知道...... :)
编辑:我知道找到所有引用,但这只提供函数的调用站点,而不是调用函数调用函数的函数的调用站点...
编辑:VS是2010年,但如果有必要,VS2012是一个选项.
根据我的理解,有两种方法可以实现有时不返回结果的函数(例如,在ppl列表中找到的人).
* - 我们忽略原始ptr版本,与bool标志配对,以及未找到版本时的异常.
boost::optional<Person> findPersonInList();
Run Code Online (Sandbox Code Playgroud)
要么
std::unique_ptr<Person> findPersonInList();
Run Code Online (Sandbox Code Playgroud)
那么有什么理由可以优先于另一个吗?
请注意,我std::thread
只是用来获取错误中的可读类型:
int main() {
const int * first;
using deref = decltype(*first);
std::thread s = std::remove_const<deref>::type{}; // const int ???
std::thread s2 = deref{}; // const int
std::thread s3 = std::remove_const<const int>::type{}; // int
}
Run Code Online (Sandbox Code Playgroud)
似乎remove_const<deref>::type
是const int
,不像int
我期望的那样可变.
注意:这个问题被简要标记为this的重复,但它不是一个完全重复的,因为我专门询问 std::optionals 。如果您关心一般情况,仍然是一个值得阅读的好问题。
假设我有嵌套的选项,像这样(愚蠢的玩具示例):
struct Person{
const std::string first_name;
const std::optional<std::string> middle_name;
const std::string last_name;
};
struct Form{
std::optional<Person> person;
};
Run Code Online (Sandbox Code Playgroud)
和这个垃圾邮件功能:
void PrintMiddleName(const std::optional<Form> form){
if (form.has_value() && form->person.has_value() && form->person->middle_name.has_value()) {
std::cout << *(*(*form).person).middle_name << std::endl;
} else {
std::cout << "<none>" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
展平此可选检查的最佳方法是什么?我做了这样的东西,它不是可变参数,但我不太关心(membr3
如果真的有必要,我可以再添加一个级别(用 重载),除此之外的一切都是糟糕的代码)。
template<typename T, typename M>
auto flatten_opt(const std::optional<T> opt, M membr){
if (opt.has_value() && (opt.value().*membr).has_value()){
return std::optional{*((*opt).*membr)};
}
return decltype(std::optional{*((*opt).*membr)}){};
}
template<typename T, typename M1, typename M2> …
Run Code Online (Sandbox Code Playgroud)