小编bol*_*lov的帖子

C++ 17 lambda capture*this

C++ 17将按值添加此对象的副本捕获,捕获规范为[*this].

这有用吗?它与捕获this有何不同?这不可能在C++ 14中实现[tmp = *this]吗?


用于解释为什么P0018R3使用[=, tmp = *this]而不是[tmp = *this]在他们的示例中的奖金.如果他们使用过[tmp = *this],那么C++ 14解决方案的所有列出的缺点都将被消除.

c++ lambda c++-faq c++17

27
推荐指数
2
解决办法
3289
查看次数

static_assert依赖于非类型模板参数(gcc和clang上的不同行为)

template <int answer> struct Hitchhiker {
  static_assert(sizeof(answer) != sizeof(answer), "Invalid answer");
};

template <> struct Hitchhiker<42> {};
Run Code Online (Sandbox Code Playgroud)

在尝试禁用常规模板实例化的同时,static_assert我发现clang即使模板未实例化,上面的代码也会生成断言错误,而gcc只有在Hitchhiker使用除了以外的参数进行实例化时才生成断言错误42.

摆弄我发现这个断言:

template <int answer> struct Hitchhiker {
  static_assert(sizeof(int[answer]) != sizeof(int[answer]), "Invalid answer");
};

template <> struct Hitchhiker<42> {};
Run Code Online (Sandbox Code Playgroud)

两个编译器的行为相同:只有在实例化通用模板时,断言才会启动.

标准说什么,哪个编译器是对的?

g++ 4.9.2
clang++ 3.50
Run Code Online (Sandbox Code Playgroud)

c++ templates dependent-name language-lawyer c++14

25
推荐指数
2
解决办法
1136
查看次数

C++ - 返回const unique_ptr

我想知道为什么我在编译时遇到错误:

const std::unique_ptr<int> get() { 
    return std::make_unique<int>(10);
}

int main() { 

    const std::unique_ptr<int> value = get();

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

我收到以下错误:

main.cpp: In function ‘int main()’:
main.cpp:10:44: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
     const std::unique_ptr<int> value = get();
Run Code Online (Sandbox Code Playgroud)

当我constget签名中删除它时,它正确编译.

有没有办法返回一个常量unique_ptr?

c++ c++11

25
推荐指数
1
解决办法
2596
查看次数

C++ 1z为什么不删除有向图和三字母?

C++ 1z将删除trigraphs.IBM严重反对这一点(此处此处),因此似乎存在删除/不删除双方的争论.

但既然决定删除三角形,为什么要留下有向图?我认为没有任何理由可以保留有关三角形的原因(这显然不足以保留三角形).

c++ standards digraphs trigraphs c++17

24
推荐指数
1
解决办法
2379
查看次数

多重继承运算符的重载分辨率()

首先,考虑一下这个C++代码:

#include <stdio.h>

struct foo_int {
    void print(int x) {
        printf("int %d\n", x);
    }    
};

struct foo_str {
    void print(const char* x) {
        printf("str %s\n", x);
    }    
};

struct foo : foo_int, foo_str {
    //using foo_int::print;
    //using foo_str::print;
};

int main() {
    foo f;
    f.print(123);
    f.print("abc");
}
Run Code Online (Sandbox Code Playgroud)

正如根据标准所预期的那样,这无法编译,因为print为了重载解析的目的在每个基类中单独考虑,因此调用是不明确的.这是Clang(4.0),gcc(6.3)和MSVC(17.0)的情况 - 请参阅此处的 godbolt结果.

现在考虑以下片段,唯一的区别是我们使用operator()而不是print:

#include <stdio.h>

struct foo_int {
    void operator() (int x) {
        printf("int %d\n", x);
    }    
};

struct foo_str {
    void operator() (const …
Run Code Online (Sandbox Code Playgroud)

c++ lambda multiple-inheritance language-lawyer overload-resolution

24
推荐指数
1
解决办法
645
查看次数

如何使用集合构建MVVM?

当涉及列表/集合时,我无法理解如何应用MVVM模式.

假设MainModel有一些属性和方法,以及包含其他DetailModel对象的列表.该DetailModel对象可以被添加,删除或重新排序.

MainView会显示相关的根模式中的一些控制,并有ListBox从列表填充.每个项目都有自己的子视图DetailModelView UserControl.

最后,有一个MainViewModel.这个属性由MainModel属性和方法支持,绑定到主视图,更改通知保持所有内容同步.(到目前为止,我对这种模式感到满意 - 如果有一些我缺少的基本内容,请更多说明这一点......)

在处理列表时,我感到困惑.我遇到了几个例子,其中MainViewModel简单地公开DetailModels了视图的列表,并且DetailModelViews直接绑定到模型.这个功能,但是有问题.它并不一贯遵循模式(不DetailViewModel存在),它促使我在我的细节模型中包含一些与UI相关的代码.我觉得MainViewModel应该公开一个DetailViewModelsUI 的列表来绑定,但我仍然坚持如何实现这样的事情!

应该如何管理两个列表(DetailModelsDetailViewModels)?我真的很困惑,因为我最初填充DetailViewModel列表,以及我应该如何处理添加,删除或更改项目的顺序,以保持它们同步!

wpf mvvm

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

clang似乎使用gcc库

这是我第一次使用clang.我注意到,引用std库的clang的任何错误都是这样的:

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:245:7:
                ^^^                  ^^^                         ^^^
Run Code Online (Sandbox Code Playgroud)

所以它看起来像clang链接 - 或者至少包括 - gcc库.

我使用的命令:clang++ -c -Wall -Wextra -Werror -g test.cpp -o test.o.(该程序有一个故意的错误只是为了证明这一点).

这怎么可能?我该怎么做才能clang使用自己的库(但不能破坏gcc)?


附加信息:

我在Ubuntu 14.04机器上.

clang++ --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix

g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)

我以前安装过多个版本(在同一时间,所使用它们update-alternatives)的gcc使用apt-get.现在我只有4.8(我卸载了其他人).我可以搞砸了吗?我从来没有安装过clang(我猜它是默认的Ubuntu).

只是为了澄清:正确的程序编译和运行clang++.

进一步的测试:我知道在他们的标准c ++ 11库(https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html)中gcc没有实现类似is_trivially_constructible和移动操作的类型,而且clang已经完整的c ++ …

c++ gcc clang

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

解除引用指针和访问数组元素之间的区别

我记得一个示例,其中演示了指针和数组之间的区别.

当作为函数参数传递时,数组衰减到指向数组中第一个元素的指针,但它们不等效,如下所示:

//file file1.c

int a[2] = {800, 801};
int b[2] = {100, 101};
Run Code Online (Sandbox Code Playgroud)
//file file2.c

extern int a[2];

// here b is declared as pointer,
// although the external unit defines it as an array
extern int *b; 

int main() {

  int x1, x2;

  x1 = a[1]; // ok
  x2 = b[1]; // crash at runtime

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

链接器不会对外部变量进行类型检查,因此在编译时不会生成错误.问题是它b实际上是一个数组,但编译单元file2不知道这一点并将其视为b指针,在尝试取消引用时会导致崩溃.

我记得当这被解释时它是完全合理的,但现在我不记得解释,也不能靠自己来解决.

所以我想问题是在访问元素时,数组如何与指针区别对待?(因为我认为无论是数组还是指针p[1]都转换为(程序集等价)- 我显然是错的).*(p + 1)p


由两个解除引用(VS 2013)所产生的组件:
注意: 1158000h …

c arrays pointers dereference

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

使用之前在if语句中定义的变量

int main() {
    if(i = 0) {
        myclass1 a = "Example1";
    }
    else {
        myclass2 a = "Example2";
    }
    cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)

我知道一种方法是通过在块外定义它,但如果a在检查条件之前我还没有确定什么类型,该i怎么办?

c++ object

21
推荐指数
5
解决办法
2661
查看次数

假设没有"并发访问",安全地将内存块"借出"给C中的另一个线程

问题

我想在一个线程中分配内存,并安全地 "释放"指向另一个线程的指针,以便它可以读取该内存.

我正在使用一种翻译成C语言的高级语言.高级语言有线程(未指定的线程API,因为它是跨平台的 - 见下文)并支持标准的C多线程原语,如原子比较交换,但它没有真正记录(没有用法示例).这种高级语言的限制是:

  • 每个线程执行一个事件处理无限循环.
  • 每个线程都有自己的本地堆,由一些自定义分配器管理.
  • 每个线程都有一个"输入"消息队列,可以包含来自任意数量的不同其他线程的消息.
  • 传递队列的消息是:
    1. 对于固定类型的消息
    2. 使用复制

现在,对于大型(不希望复制)或可变大小(我认为数组大小是类型的一部分)消息,这是不切实际的.我想发送这样的消息,这里是我想要实现它的大纲:

  • 消息(请求回复)可以存储"有效负载"内联(复制,固定限制总值大小),或指向发送方堆中数据的指针
  • 消息内容(发送者堆中的数据)由发送线程拥有(分配和释放)
  • 接收线程在完成消息内容时向发送线程发送确认
  • "发送"线程在发送之后不得修改消息内容,直到收到(ack).
  • 应该永远是对内存并行读访问被写入,写之前完成.这应该由消息队列work-flow保证.

我需要知道如何确保这没有数据竞争.我的理解是我需要使用内存栅栏,但我不完全确定哪一个(ATOMIC_RELEASE,...)以及循环中的位置(或者我是否需要任何内容​​).


便携性考虑因素

因为我的高级语言需要跨平台,所以我需要得到答案:

  • Linux,MacOS以及可选的Android和iOS
    • 使用pthreads原语来锁定消息队列:pthread_mutex_initpthread_mutex_lock+pthread_mutex_unlock
  • 视窗
    • 使用Critical Section Objects来锁定消息队列:InitializeCriticalSectionEnterCriticalSection+LeaveCriticalSection

如果它有帮助,我假设以下架构:

  • 用于Windows/Linux/MacOS的英特尔/ AMD PC架构(?).
  • 适用于iOS和Android的未知(ARM?)

并使用以下编译器(您可以假设所有这些编译器的"最近"版本):

  • Windows上的MSVC
  • Linux上的铿锵声
  • Xcode在MacOS/iOS上
  • 适用于Android的CodeWorks for Android

到目前为止,我只在Windows上构建,但是当应用程序完成后,我希望以最少的工作将其移植到其他平台.因此,我试图从一开始就确保跨平台兼容性.


试图解决方案

这是我假设的工作流程:

  1. 读取队列中的所有消息,直到它为空(仅当它完全为空时才阻塞).
  2. 在这里叫一些"记忆围栏"?
  3. 读取消息内容(消息中指针的目标),并处理消息.
    • 如果消息是"请求",则可以处理该消息,并将新消息缓冲为"回复".
    • 如果消息是"回复",则可以释放原始"请求"的消息内容(隐式请求"确认").
    • 如果消息是"回复",并且它本身包含指向"回复内容"的指针(而不是"内联回复"),那么也必须发送"回复确认".
  4. 在这里叫一些"记忆围栏"?
  5. 将所有缓冲的消息发送到适当的消息队列中. …

c multithreading thread-safety nim-lang

21
推荐指数
1
解决办法
597
查看次数