小编Mor*_*enn的帖子

并行写入相同的值

我有一个程序会产生多个线程,这些线程可能会将完全相同的值写入完全相同的内存位置:

std::vector<int> vec(32, 1); // Initialize vec with 32 times 1
std::vector<std::thread> threads;

for (int i = 0 ; i < 8 ; ++i) {
    threads.emplace_back([&vec]() {
        for (std::size_t j = 0 ; j < vec.size() ; ++j) {
            vec[j] = 0;
        }
    });
}

for (auto& thrd: threads) {
    thrd.join();
}
Run Code Online (Sandbox Code Playgroud)

在此简化的代码中,所有线程都可以尝试将完全相同的值写入中的相同内存位置vec。这是一场数据竞赛可能会触发未定义的行为,还是安全的,因为在再次连接所有线程之前从不读取值?

如果存在潜在的危险数据竞争,那么使用std::vector<std::atomic<int>>std::memory_order_relaxed存储的替代方法足以防止数据竞争吗?

c++ multithreading memory-model race-condition c++11

4
推荐指数
1
解决办法
411
查看次数

三元语句中的C逗号

int m = 5, d = 12, y = 1975, val;
    // May 12, 1975
Run Code Online (Sandbox Code Playgroud)

有人可以在下面的代码行中解释逗号运算符的功能/目的:

val = (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;
Run Code Online (Sandbox Code Playgroud)

上述行写由麦克·基思来计算给定日期(d =天,M =月,Y =年)一周中的一天.其中星期日= 0,星期一= 1,星期二= 2,星期三= 3,星期四= 4,星期五= 5,星期六= 6.我知道如果d + = m <3,则y--执行,否则y -2执行.我不明白的是y-2之后逗号的目的.

c ternary-operator comma operator-keyword

4
推荐指数
2
解决办法
1979
查看次数

对于循环与使用相对较旧的编译器的标准库算法

我知道当代码中没有任何令人困惑的for循环时,代码会更好.在可能的情况下重用标准库算法总是好的.但是,我发现迭代器和算法的语法看起来真的很混乱.

我想从我当前的项目中给出一个真实的例子:我想将内容复制vector<vector<QString>> invector<QVariant> out.我看不出以下区别:

for (int i = 0; i < in[0].size(); i++ ) 
{ 
    if(in[0][i].isNull() || in[0][i].isEmpty() ) 
        out[i] = "NONE";
    else
        out[i] = in[0][i];
}
Run Code Online (Sandbox Code Playgroud)

然后:

std::transform(in[0].begin(), in[0].end(), out.begin(), [](const QString& a)->QVariant{
    if(a.isNull() || a.isEmpty() ) 
        return "NONE";
    else
        return a;
}); 
Run Code Online (Sandbox Code Playgroud)

由于我们有visual studio 2012,我甚至必须输入我的lambda的返回值.使用范围之后:

in[0].map!( a => a.isNull() || a.isEmpty() ? "NONE" : a ).copy(out);
Run Code Online (Sandbox Code Playgroud)

在D语言中,我根本无法忍受std::transform上面的代码.我甚至不确定它是否比基本for循环更好.我的问题是:使用std::transform上面的代码比for循环好吗?

c++ algorithm c++11

4
推荐指数
1
解决办法
337
查看次数

std::nullopt_t 构造函数原理

本页所述

std::nullopt_t必须是 aLiteralType并且不能有默认构造函数。它必须有一个constexpr构造函数,该构造函数采用某种实现定义的文字类型。...注释 nullopt_tDefaultConstructible支持op = {};op = nullopt;作为脱离可选对象的语法。

...而且,一个可能的实现是

struct nullopt_t {
    constexpr nullopt_t(int) {}
};
Run Code Online (Sandbox Code Playgroud)

实际上,在阅读本文后,我不太明白其背后的原理。

(1) 为什么nullopt_t不做DefaultConstructible?我不太明白“......支持两者......”部分。

(2) 为什么可能的构造函数采用int,而boost::none_t采用空类型boost::none_t::init_tag?这两种实现有何不同?

c++ c++11 c++14 c++17

4
推荐指数
1
解决办法
443
查看次数

标准C++事务内存状态

C++ 17的事务性内存提议的当前状态是什么.是否会包含在标准中,旨在包含在标准C++的某些未来版本中,或者仅仅是一个实验性的概念验证功能,其标准化状态仍未确定?

我问,因为一些标准化委员会的文件似乎在这里提供了相互矛盾的沟通.一方面,我们有P0265R0(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0265r0.pdf)说交易记忆不会标准化,另一方面手 - 有一篇由Stroustrup撰写的N4492论文(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4492.pdf),其中的事务内存列在C++ 17功能列表中.

c++ transactional-memory c++17

4
推荐指数
1
解决办法
482
查看次数

如何使用`std :: basic_istream <std :: byte>`之类的东西

此问题旨在使用std::byte标准输入输出.

是否有计划增加适当的功能重载read(_bytes)write(_bytes)到的接口basic_istream<CharT>,并basic_ostream<CharT>在将来的标准是什么?有什么理由反对呢?我知道CharT*应该保留-overloads.我该怎么办std::byte?我目前在我的项目功能中定义

std::istream& read(std::istream&, std::byte*, std::streamsize)
std::ostream& write(std::ostream&, const std::byte*, std::streamsize)
Run Code Online (Sandbox Code Playgroud)

这些使用reinterpret_cast<>char*RESP.const char*但我相信这取决于它的大小char.我错了吗?是char永远1 byte

我试图制作,std::basic_istream<std::byte>但它缺少std::char_traits<std::byte>等等.有人做过这种事吗?

c++ io std c++17

4
推荐指数
2
解决办法
587
查看次数

c ++ std :: vector std :: sort无限循环

每当我试图对导致无限循环的对象矢量进行排序时,我就遇到了一个问题.我正在使用我传递给sort函数的自定义比较函数.

我能够通过在两个对象相等而不是true时返回false来解决问题但我并不完全理解解决方案.我认为这是因为我的比较功能违反了cplusplus.com上列出的规则:

比较函数对象,如果第一个参数位于其定义的特定严格弱顺序中的第二个参数之前,则返回两个与该范围中包含的相同类型的值,否则返回false.

任何人都可以提供更详细的解释吗?

c++ sorting stdvector

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

gmpxx.h:没有这样的文件或目录

我刚刚从Sourceforge 的官方项目页面安装了一个全新的mingw(32位)副本.我在包中安装了所有内容,所有编译器等等.然后我从这里下载gmp for MinGW.我将gmp-5.0.1-1-mingw32-src.tar.lzma提取到我的mingw文件夹中,然后./pkgbuild从那里运行.它继续运行几分钟,然后打印出类似的东西COMPLETED EVERYTHING OK, EVERYTHING PASS.

然后我写下这个简单的例子,检查它是否会起作用:

#include <gmpxx.h>

int main (void)
{
  mpz_class a, b, c;

  a = 1234;
  b = "-5678";
  c = a+b;
  cout << "sum is " << c << "\n";
  cout << "absolute value is " << abs(c) << "\n";

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后使用编译它g++ mycxxprog.cc -lgmpxx -lgmp.我得到的唯一答案是:

Fatal error: gmpxx.h: No such file or directory.
Run Code Online (Sandbox Code Playgroud)

有人有任何暗示吗?我真的不知道该怎么办......

c++ mingw gmp mingw32

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

模板参数的"部分应用"

我有以下"主"模板:

template <
        template <typename> class S
    > struct TT { /*...*/ };
Run Code Online (Sandbox Code Playgroud)

和我想要使用的模板TT:

template <int N, typename T> struct S1 {};
Run Code Online (Sandbox Code Playgroud)

特别是,我想使用类似的东西

TT< S1<5> > t2; // "Invalid template arguments" here
Run Code Online (Sandbox Code Playgroud)

它是模板的一种部分应用.我知道Boost.MPL涉及这种东西.问题是我已经有一些使用TT和模板的代码了

template <typename T> struct S2 {}; // S3, S4…
Run Code Online (Sandbox Code Playgroud)

它被送到TT.

所以,问题是:我怎么能使用S1TT具有最小的修改现有的代码.如果必须使用Boost.MPL,请告诉我最合适的解决方案.

c++ templates boost-mpl

3
推荐指数
1
解决办法
625
查看次数

如何判断是否将可选参数传递给函数C.

编辑3:对于代码本身,一起检查第一个答案或这篇文章的结尾.

正如标题中所述,我试图找到一种方法来判断是否将可选参数传递给函数.我想要做的就是几乎所有动态语言都处理它们的子串函数.下面是我的目前,但它不起作用,因为我不知道如何判断/何时使用该东西.

char *substring(char *string,unsigned int start, ...){
    va_list args;
    int unsigned i=0;
    long end=-1;
    long long length=strlen(string);
    va_start(args,start);
    end=va_arg(args,int);
    va_end(args);
    if(end==-1){
        end=length;
    }
    char *to_string=malloc(end);
    strncpy(to_string,string+start,end);
    return to_string;
}
Run Code Online (Sandbox Code Playgroud)

基本上我想仍然能够不包括我想要的字符串的长度,只是让它到字符串的末尾.但我似乎找不到办法做到这一点.由于也无法知道在C中传递的参数数量,因此我首先想到了这一点.

编辑:这里做的新方法是当前的代码.

#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2 (0)
char *substring(char *string,unsigned int start, int end){
    int unsigned i=0;
    int num=0;
    long long length=strlen(string);
    if(end==0){
        end=length;
    }
    char *to_string=malloc(length);
    strncpy(to_string,string+start,end);
    return to_string;
}
Run Code Online (Sandbox Code Playgroud)

然后在一个文件中我调用test.c来查看它是否有效.

#include "functions.c"
int main(void){
    printf("str:%s",substring("hello world",3,2));
    printf("\nstr2:%s\n",substring("hello world",3));
return 0;
}
Run Code Online (Sandbox Code Playgroud)

functions.c有一个包含for functions.h的函数,它包含了所有需要的东西.这是clang输出(因为clang似乎通常会提供更多细节.

In file …
Run Code Online (Sandbox Code Playgroud)

c substring variadic-functions p99

3
推荐指数
1
解决办法
916
查看次数