小编aki*_*kim的帖子

为什么自动返回类型会改变重载分辨率?

感谢decltype作为返回类型,C++ 11使得引入装饰器非常容易.例如,考虑这个类:

struct base
{
  void fun(unsigned) {}
};
Run Code Online (Sandbox Code Playgroud)

我想用其他功能来装饰它,因为我会用不同种类的装饰做几次,所以我首先介绍一个decorator简单地转发所有内容的课程base.在真实的代码中,这是通过以下方式完成的,std::shared_ptr这样我就可以删除装饰并恢复"裸"对象,并且所有内容都是模板化的.

#include <utility> // std::forward
struct decorator
{
  base b;

  template <typename... Args>
  auto
  fun(Args&&... args)
    -> decltype(b.fun(std::forward<Args>(args)...))
  {
    return b.fun(std::forward<Args>(args)...);
  }
};
Run Code Online (Sandbox Code Playgroud)

完美的转发,decltype真是太棒了.在实际代码中,我实际上使用的是一个只需要函数名称的宏,其余的都是样板文件.

然后,我可以引入一个derived为我的对象添加功能的类(derived不正确,同意,但它有助于理解这derived是一种base,虽然不是通过继承).

struct foo_t {};
struct derived : decorator
{
  using decorator::fun; // I want "native" fun, and decorated fun.
  void fun(const foo_t&) {}
};

int main()
{
  derived d; …
Run Code Online (Sandbox Code Playgroud)

c++ auto return-type-deduction c++14

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

地址清理Boost.Python模块

我的项目包括一个大型C++库和Python绑定(通过Boost.Python).测试套件主要是在Python绑定之上编写的,我想用清理程序运行它,从ASAN开始.

我正在运行macOS(10.13.1 FWIW,但我也遇到了以前版本的问题),我似乎找不到在Python模块上运行ASAN的方法(我非常怀疑这与Boost.Python有关) ,我想它与其他技术一样).

这是一个简单的Python模块:

// hello_ext.cc
#include <boost/python.hpp>

char const* greet()
{
  auto* res = new char[100];
  std::strcpy(res, "Hello, world!");
  delete [] res;
  return res;
}

BOOST_PYTHON_MODULE(hello_ext)
{
  using namespace boost::python;
  def("greet", greet);
}
Run Code Online (Sandbox Code Playgroud)

这是我使用的Makefile,为MacPorts制作:

// Makefile
CXX = clang++-mp-4.0
CXXFLAGS = -g -std=c++14 -fsanitize=address -fno-omit-frame-pointer
CPPFLAGS = -isystem/opt/local/include $$($(PYTHON_CONFIG) --includes)
LDFLAGS = -L/opt/local/lib
PYTHON = python3.5
PYTHON_CONFIG = python3.5-config
LIBS = -lboost_python3-mt $$($(PYTHON_CONFIG) --ldflags)

all: hello_ext.so

hello_ext.so: hello_ext.cc
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ $< $(LIBS)

check: …
Run Code Online (Sandbox Code Playgroud)

c++ python boost-python address-sanitizer

19
推荐指数
2
解决办法
640
查看次数

改变语法以消除移位减少if-then-else中的冲突

如何针对给定语法删除bison的shift-reduce冲突?

 selection-stmt -> if ( expression ) statement |
                      if ( expression ) statement else statement
Run Code Online (Sandbox Code Playgroud)

提供修改后的语法的解决方案将受到高度赞赏.

bison shift-reduce-conflict

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

使用clang ++,-fvisibility = hidden,typeinfo和type-erasure

这是我在Mac OS X上使用clang ++面临的问题的缩小版本.这是经过严格编辑以更好地反映真正的问题(第一次尝试描述问题并没有表现出问题).

失败

我在C++中有一大块软件,在目标文件中有大量符号,所以我-fvisibility=hidden用来保持我的符号表小.众所周知,在这种情况下,必须特别注意vtable,我想我遇到了这个问题.然而,我不知道如何以一种令gcc和clang取悦的方式优雅地解决它.

考虑一个base具有向下转换运算符asderived类,以及包含一些有效负载的类模板.pair base/ derived<T>用于实现类型擦除:

// foo.hh

#define API __attribute__((visibility("default")))

struct API base
{
  virtual ~base() {}

  template <typename T>
  const T& as() const
  {
    return dynamic_cast<const T&>(*this);
  }
};

template <typename T>
struct API derived: base
{};

struct payload {}; // *not* flagged as "default visibility".

API void bar(const base& b);
API void baz(const base& b);
Run Code Online (Sandbox Code Playgroud)

然后我有两个不同的编译单元提供类似的服务,我可以将其近似为相同功能的两倍:向下转换basederive<payload>:

// bar.cc
#include "foo.hh" …
Run Code Online (Sandbox Code Playgroud)

c++ visibility g++ elf clang++

16
推荐指数
1
解决办法
6856
查看次数

为什么std :: abs返回签名类型

当我比较一个std::abs(int)和一个时,我正在收到有关签名与无签名比较的警告unsigned.事实上,std::abs返回签署的值.为什么选择这个?它将解决负值的问题,其绝对值不能用有符号的类型表示.

然后,是否有比这更清洁(即没有演员表)的东西以避免警告?

#include <cassert>
#include <cstdlib>

// max(1, lhs + rhs). (lhs must be > 0)
unsigned add(unsigned lhs, int rhs)
{
  return
    (0 < rhs || static_cast<unsigned>(-rhs) < lhs
     ? rhs + lhs
     : 1);
}

int main()
{
  assert(add(42, -41) == 1);
  assert(add(42, 0) == 43);
  assert(add(42, 1) == 43);
  assert(add(42, -51) == 1);
}
Run Code Online (Sandbox Code Playgroud)

c++ unsigned signed gcc-warning

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

C++ 11:重载无法解析递归的decltype

在下面的代码中,我正在尝试构建一个类型的网格.例如,在float和之间int,将结果推广到float:

float join(float f, int)   { return f; }
float join(float f, float) { return f; }
Run Code Online (Sandbox Code Playgroud)

然后我介绍一种wrapper类型:

template <typename Inner>
struct wrapper
{
  using inner_t = Inner;
  inner_t value;
};
Run Code Online (Sandbox Code Playgroud)

join操作行为很自然:

template <typename Inner1, typename Inner2>
auto
join(const wrapper<Inner1>& w1, const wrapper<Inner2>& w2)
  -> wrapper<decltype(join(w1.value, w2.value))>
{
  return {join(w1.value, w2.value)};
}
Run Code Online (Sandbox Code Playgroud)

它也可以join用"标量"类型编辑:

template <typename Inner1, typename T2>
auto
join(const wrapper<Inner1>& w1, const T2& value2)
  -> wrapper<decltype(join(w1.value, value2))> …
Run Code Online (Sandbox Code Playgroud)

c++ overloading decltype c++11 trailing-return-type

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

ASTs:更喜欢继承还是变体?

在面向对象的语言中,使用简单的层次结构(Composite模式)实现AST(抽象语法树)并通过访问者遍历它们是相当普遍的.

在函数式编程语言中,使用变量/和类型,然后使用模式匹配,是正确的方法.

C++同时具有继承和Boost.Variants.我已经使用继承编写了几个AST层次结构,但我想从那些使用变体方法的人那里得到一些反馈.我想知道哪一个是"最好的",在性能(时间和空间)方面,而且在可维护性(易于创建树和遍历它们)方面.

我对实现hash-consing(保留每个公共子树的单个副本)的经验特别感兴趣,可能还有Boost.Flyweight.

谢谢!

c++ composite abstract-syntax-tree boost-variant

8
推荐指数
0
解决办法
424
查看次数

规则空缺右侧的符号

当使用带有空右侧的规则编写("理论")语法时,总是使用诸如ε(或1)之类的符号来使这个空白显式:

A ? ? | a A
Run Code Online (Sandbox Code Playgroud)

Yacc和其他人的这种语法看起来就像

a: | 'a' a
Run Code Online (Sandbox Code Playgroud)

或"更糟"

a:       { $$ = new_list(); }
 | a 'a' { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

事实上,在"真实世界语法"(Yacc,Bison等)规则的这个空的右侧部分没有明确标记为空的麻烦我:很容易错过rhs空的事实,或者更糟糕的是:忘记插入|并实际使用中规则操作:

a:       { $$ = new_list(); }
   a 'a' { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

1)我不知道有任何工具可以提供显式空rhs的方法.有吗?

Bison的未来版本可能支持专用符号,在非空rhs中使用时会出现错误,而在留下隐式空rhs时会出现警告.

2)人们认为这有用吗?

3)你建议的符号是什么?

目前,候选人是$empty:

a: $empty { $$ = new_list(); }
 | a 'a'  { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

编辑

选择的语法是%empty:

a: %empty { $$ = …
Run Code Online (Sandbox Code Playgroud)

yacc bison parser-generator

7
推荐指数
2
解决办法
9038
查看次数

在静态lib配置中使用Clang清理程序配置autotools项目?

编辑:如果它的TLDR,只是跳到底部.我问的地方:如何配置autotools项目以使用静态库?

我正在使用几个开源库,我正在尝试在Clang的清洁剂下运行他们的测试套件.要在Clang清理程序下运行,我们需要(1)指定一些选项,以及(2)根据需要链接Clang的Compiler-RT中的静态库.注意:没有动态库或共享对象.

设置选项很简单:

export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib/clang/3.3/lib/darwin/
export CC=/usr/local/bin/clang
export CXX=/usr/local/bin/clang++
export CFLAGS="-g3 -fsanitize=address -fsanitize=undefined"
export CXXFLAGS="-g3 -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr"

./configure
Run Code Online (Sandbox Code Playgroud)

但是,这将生成一些存档警告(AR运行时)和链接错误(LD运行时)和未定义的符号.该消息类似于:

libjpeg.a(jmemmgr.o): In function `do_sarray_io':
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to
`__ubsan_handle_type_mismatch'
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to
`__ubsan_handle_type_mismatch'
/home/jwalton/jpeg-6b/jmemmgr.c:696: undefined reference to
`__ubsan_handle_type_mismatch'
Run Code Online (Sandbox Code Playgroud)

我知道需要链接的库.对于我使用的消毒剂,他们是libclang_rt.asan_osx.alibclang_rt.ubsan_osx.a(或libclang_rt.full-x86_64.alibclang_rt.ubsan-x86_64.a在Linux上).

为了提供库,我然后导出以下内容.注意:它是LIBS,而不是LDLIBS大多数其他make相关工具所预期的.

export LIBS="/usr/local/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx.a \
             /usr/local/lib/clang/3.3/lib/darwin/libclang_rt.ubsan_osx.a"
Run Code Online (Sandbox Code Playgroud)

这导致以下configure问题:

configure: error: cannot run C compiled programs.
If …
Run Code Online (Sandbox Code Playgroud)

autotools configure clang static-libraries sanitizer

6
推荐指数
2
解决办法
2340
查看次数

使用 rdbuf 复制流在空输入时失败

使用rdbuf以下方法将流复制到另一个流中是一种众所周知的方法:

#include <iostream>
#include <fstream>

int main()
{
  std::ifstream in{"/tmp/foo.txt"};
  std::cerr << in.rdbuf();
  std::cerr << "Done\n";
}
Run Code Online (Sandbox Code Playgroud)

但是,这会中断(= 设置坏位) my cerrwhen/tmp/foo.txt为空。结果,Done\n不显示。

这是为什么?使用 G++/libstdc++/GNU Linux 和 Clang++/libc++/OS X 观察。

c++ stream ostream

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