小编Chr*_*eck的帖子

如何在github wiki页面制作"剧透"文本?

我正在尝试制作在鼠标悬停之前不可见的文本,或者具有"显示"/"隐藏"按钮或其他一些东西,以便在用户以某种方式与其交互之前它是不可见的.

我正在尝试在github wiki页面上执行此操作.(特别是它是一个简短的自我测验.)

基本上我想获得与>!标记的SO相似的效果:

HOHO!剧透文字!

正如这些 文章所述.

相同的标记在github中不起作用,我猜它是SO扩展?

我在github 上的注释中看到了关于使用扰流文本的问题,该文章已经关闭,但我认为维基页面可能有不同的答案,或基于HTML或其他东西的不同解决方案?

有没有人知道是否有办法做到这一点,或者如果绝对不幸的是不可能?

html github github-flavored-markdown

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

Clang格式换行符

我正在寻找一个clang-format设置来防止该工具删除换行符.

例如,我将我的ColumnLimit设置设置为120,这是我重新格式化一些示例代码时会发生的情况.

之前:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string> {
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines"
   };
}

int main()
{
   auto vec = get_vec();
}
Run Code Online (Sandbox Code Playgroud)

后:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string>{"this is a test", "some of the lines are longer", "than other, but I would like",
         "to keep them on separate lines"}; …
Run Code Online (Sandbox Code Playgroud)

c++ code-formatting clang clang-format

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

C++参数包,被限制为具有单一类型的实例?

从C++ 11开始,我们可以创建可以接受任何参数序列的模板函数:

template <typename... Ts>
void func(Ts &&... ts) {
   step_one(std::forward<Ts>(ts)...);
   step_two(std::forward<Ts>(ts)...);
}
Run Code Online (Sandbox Code Playgroud)

但是,假设在每个参数具有相同类型的情况下调用我的函数真的是有意义的 - 任何数量的参数都可以.

这样做的最佳方法是什么,即在这种情况下是否有一种很好的方法来约束模板以生成一个很好的错误消息,或者理想情况下,func当参数不匹配时,可以避免参与重载解析?


如果它有帮助我可以使它真正具体:

假设我有一些结构:

struct my_struct {
  int foo;
  double bar;
  std::string baz;
};
Run Code Online (Sandbox Code Playgroud)

现在,我希望能够执行以下操作:打印结构的成员以进行调试,序列化和反序列化结构,按顺序访问结构的成员等.我有一些代码可以帮助解决这个问题:

template <typename V>
void apply_visitor(V && v, my_struct & s) {
  std::forward<V>(v)("foo", s.foo);
  std::forward<V>(v)("bar", s.bar);
  std::forward<V>(v)("baz", s.baz);
}

template <typename V>
void apply_visitor(V && v, const my_struct & s) {
  std::forward<V>(v)("foo", s.foo);
  std::forward<V>(v)("bar", s.bar);
  std::forward<V>(v)("baz", s.baz);
}

template <typename V>
void apply_visitor(V && v, my_struct && s) { …
Run Code Online (Sandbox Code Playgroud)

c++ templates visitor variadic-templates c++11

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

使用clang格式缩进预处理程序指令

我正在开发一个c ++项目,我正在使用它#pragma omp.我使用精彩的clang格式来整理,但它总是删除所有预处理器指令的缩进.有没有办法改变这种行为?或者是否有其他格式化工具更值得推荐?或者我应该避免使用这些工具?

c++ code-cleanup clang-format

23
推荐指数
4
解决办法
3745
查看次数

constexpr头文件中的全局常量和odr

不幸的是,我有点困惑constexpr,在头文件中声明的全局常量和odr.

简而言之:我们可以从这里结束

https://isocpp.org/files/papers/n4147.pdf

constexpr MyClass const MyClassObj () { return MyClass {}; }
constexpr char const * Hello () { return "Hello"; }
Run Code Online (Sandbox Code Playgroud)

比...好

constexpr MyClass const kMyClassObj = MyClass {};
constexpr char const * kHello = "Hello";
Run Code Online (Sandbox Code Playgroud)

如果我想"只使用"那些全局声明/定义的实体并且不想考虑我如何使用它们,那么在头文件中定义全局变量?

c++ linkage language-lawyer constexpr c++11

19
推荐指数
1
解决办法
7252
查看次数

为什么operator void*()转换函数被添加到C++流类中?

operator void*() constC++流类中有一个转换函数.这样所有流对象都可以隐式转换为void*.在与SO的程序员交互过程中,他们建议我不要使用,void*除非你有充分的理由使用它.void*是一种删除类型安全和错误检查的技术.因此,由于该转换功能的存在,以下程序完全有效.这是C++标准库中的一个缺陷.

#include <iostream>
int main()
{
       delete std::cout;
       delete std::cin;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看现场演示.

上述程序在C++ 03中有效,但在C++ 11及更高版本的编译器中编译失败,因为此转换函数已被删除.但问题是,如果它是危险的,它是C++标准库的一部分?允许将流对象转换为的目的是void*什么?有什么用?

c++ void-pointers c++-standard-library delete-operator c++11

13
推荐指数
2
解决办法
1902
查看次数

`*dynamic_cast <T*>(...)`是什么意思?

最近我查看了一个开源项目的代码,我看到了一堆表单的声明T & object = *dynamic_cast<T*>(ptr);.

(实际上这是在宏中发生的,用于声明遵循类似模式的许多函数.)

对我而言,这看起来像是一种代码味道.我的理由是,如果你知道演员阵容会成功,那么为什么不使用static_cast?如果你不确定,那么你不应该使用断言进行测试吗?由于编译器可以假设任何指针*都不是null.

我问过一位关于irc的开发者,他说,他认为static_cast沮丧是不安全的.他们可以添加一个断言,但即使他们没有,他说你仍然会得到一个空指针取消引用并在obj实际使用时崩溃.(因为,在失败时,dynamic_cast会将指针转换为null,然后当您访问任何成员时,您将从某个非常接近零的值的地址读取,操作系统将不允许这样做.)如果使用a static_cast,和它变坏了,你可能会得到一些内存损坏.因此,通过使用该*dynamic_cast选项,您可以在速度上进行折衷,以获得更好的可调试性.你没有为断言付费,相反,你基本上依靠操作系统来捕获nullptr dereference,至少这是我所理解的.

我当时接受了那个解释,但它让我感到困扰,我又想了一些.

这是我的推理.

如果我理解标准权利,static_cast指针转换基本上意味着做一些固定的指针算术.也就是说,如果我有A * a,我静将它转换为一个相关的类型B *,什么编译器实际上正在与做的就是添加一些偏移指针,偏移量只取决于类型的布局A,B(和其可能的C++实现).void *在静态演员之前和之后,可以通过静态铸造指针和输出它们来测试该理论.我希望如果你看一下生成的程序集,static_cast将会变成"向指针对应的寄存器添加一些固定常量".

一个dynamic_cast指针强制手段,首先检查RTTI和只做静态浇铸如果基于动态类型是有效的.如果不是,那就回来吧nullptr.于是,我想到的是,编译器会在某个点扩大为一个函数dynamic_cast<B*>(ptr),其中ptr的类型是A*到像表达

(__validate_dynamic_cast_A_to_B(ptr) ? static_cast<B*>(ptr) : nullptr)
Run Code Online (Sandbox Code Playgroud)

但是,如果我们再*在dynamic_cast的结果,*nullptr是UB,因此我们看好隐含的nullptr分支从未发生过.并且合规编译器被允许从中"向后推"并消除空检查,这是克里斯拉特纳着名的博客文章中的一个点驱动的家.

如果测试函数__validate_dynamic_cast_A_to_B(ptr)对优化器是不透明的,即它可能有副作用,那么优化器就无法摆脱它,即使它"知道"nullptr分支没有发生.但是,这个函数可能对优化器不透明 - 可能它对其可能的副作用有很好的理解. …

c++ dynamic-cast casting undefined-behavior c++11

12
推荐指数
1
解决办法
783
查看次数

这个简单的C++程序使用<locale>是否正确?

这个代码似乎在(ubuntu可信赖)版本的gcc和clang中运行正常,并且在Win 7中通过mingw运行...最近我升级到Wily并且使用clang崩溃在这里进行构建.

#include <iostream>
#include <locale>
#include <string>

int main() {
  std::cout << "The locale is '" << std::locale("").name() << "'" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

有时它是一个乱码的字符串Aborted: Core dumped,有时是它的invalid free.

$ ./a.out 
The locale is 'en_US.UTF-8QX???X??????0?????P?????\?(??\?(??\?(??h??t?????????????y???????????????????en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_UP????`?????????????????????????p???????????@??????????????`?????????????p????????????????????@??@??@??`????????p????????????0??P??p???qp??!en_US.UTF-8Q?[?????\?(??\?(??\?(???????????@?? ?????P?????0?????P?????\?(??\?(??\?(?????????????????????(??4??@??L??en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!?v[??????????????@?? ?????P?????0?????P?????\?(??\?(???(??h??t??????????????????????????????en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!??[?? ????[???????7????7??.,!!x?[??!??[??!?[??@???????????@?? ?????P?????0?????P?????\?(??\?(??\?(??(??4??@??L??X??d??p??|????????????n_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8?Aborted (core dumped)

$ ./a.out 
The locale is 'en_US.UTF-8QX\%?QX\%?Q?G?0H??H?PI??I?\:|?Q\D|?Q\>|?QhK?tK??K??K??K??K??Q?K??K??K??K??K??K?en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8?
*** Error in `./a.out': free(): invalid pointer: 0x0000000000b04a98 ***
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

(上述两个节目输出都大大缩短,或者它们不适合这个问题.)

我也在Coliru上也获得了无效免费.

但这与cppreference上的示例代码非常相似:

#include <iostream>
#include <locale>
#include <string>

int main()
{ …
Run Code Online (Sandbox Code Playgroud)

c++ locale clang c++11

10
推荐指数
1
解决办法
782
查看次数

标题中的字符串 - 这是否违反了ODR?

考虑以下带有两个编译单元的程序.


// a.hpp

class A {
  static const char * get() { return "foo"; }
};

void f();
Run Code Online (Sandbox Code Playgroud)
// a.cpp

#include "a.hpp"
#include <iostream>

void f() {
  std::cout << A::get() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
// main.cpp

#include "a.hpp"
#include <iostream>

void g() {
  std::cout << A::get() << std::endl;
}

int main() {
  f();
  g();
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因需要创建全局字符串常量是很常见的.以完全天真的方式执行此操作会导致链接器问题.通常,人们在标题中放置一个声明,在单个编译单元中放置一个定义,或者使用宏.

我的印象是,使用函数这样做(如上所示)是"好的",因为它是一个inline函数,链接器消除了生成的任何重复副本,并且使用此模式编写的程序似乎工作正常.但是,现在我怀疑它是否真的合法.

该函数A::get在两个不同的转换单元中使用,但它是隐式内联的,因为它是一个类成员.

[basic.def.odr.6]其中声明:

对于具有外部链接(7.1.2)的...内联函数,可以有多个定义...在程序中,每个定义出现在不同的翻译单元中,并且定义满足以下要求.鉴于这样一个名称D在一个以上的翻译单元中定义的实体,那么
- 每个定义D应由相同的令牌序列组成; 并且
- 在每个定义中D,相应的名称,根据3.4查询,应指D在重叠决议(13.3)之后和部分模板专业化匹配后(14.8)定义的实体,或应引用同一实体. .3),除非名称可以引用具有内部链接或没有链接的非易失性const对象,如果该对象在所有定义中具有相同的文字类型D …

c++ one-definition-rule language-lawyer c++11 c++14

10
推荐指数
1
解决办法
446
查看次数

Lua coroutines - setjmp longjmp clobbering?

在不久前的博客文章中,Scott Vokes描述了与lua使用C函数实现协程相关的技术问题,setjmp并且longjmp:

Lua协同程序的主要限制是,由于它们是用setjmp(3)和longjmp(3)实现的,所以你不能用它们从Lua调用C代码调用回调用回调用C的Lua,因为嵌套的longjmp将破坏C函数的堆栈帧.(这是在运行时检测到的,而不是静默失败.)

我没有发现这在实践中是一个问题,我不知道有什么方法可以修复它而不损坏Lua的可移植性,这是我最喜欢的Lua之一 - 它几乎可以运行任何ANSI C编译器和适度的空间.使用Lua意味着我可以轻装上阵.:)

我已经使用了很多协同程序,我认为我已经广泛地理解了发生了什么setjmp,longjmp做了什么和做了什么,但是我在某个时候读到了它,并意识到我并没有真正理解它.为了弄明白这一点,我尝试制作一个我认为应该根据描述引起问题的程序,相反它似乎工作正常.

然而,我看到其他一些地方人们似乎声称存在问题:

问题是:

  • 在什么情况下,由于C函数堆栈框架遭到破坏,lua协同程序无法工作?
  • 到底是什么结果?"在运行时检测到"是否意味着,lua恐慌?或者是其他东西?
  • 这是否仍会影响lua(5.3)的最新版本,或者这实际上是5.1问题还是什么?

这是我制作的代码.在我的测试中,它与lua 5.3.1链接,编译为C代码,测试本身在C++ 11标准下编译为C++代码.

extern "C" {
#include <lauxlib.h>
#include <lua.h>
}

#include <cassert>
#include <iostream>

#define CODE(C) \
case C: { \
  std::cout << "When returning to " << where << " got code '" #C "'" << std::endl; \
  break; \
}

void handle_resume_code(int code, const char * where) {
  switch (code) {
    CODE(LUA_OK) …
Run Code Online (Sandbox Code Playgroud)

c c++ lua coroutine longjmp

8
推荐指数
1
解决办法
1286
查看次数