小编Jac*_*kie的帖子

GCC和Clang不同意C++ 17 constexpr lambda捕获

考虑这个将变量声明为constexpr的示例,通过lambda中的副本捕获它,并声明另一个constexpr变量,该变量是constexpr函数从原始变量展开非类型模板参数的结果.

#include <utility>

template<int I>
constexpr auto unwrap(std::integral_constant<int, I>) {
  return I;
}

int main() {
  constexpr auto i = std::integral_constant<int, 42>{};
  constexpr auto l = [i]() {
    constexpr int x = unwrap(i);
  };
}
Run Code Online (Sandbox Code Playgroud)

Clang(trunk)接受此代码.(wandbox)

GCC(主干)失败,出现以下错误消息(wandbox):

lambda_capture.cpp:11:31: error: the value of ‘i’ is not usable in a constant expression
     constexpr int x = unwrap(i);
                               ^
lambda_capture.cpp:10:28: note: ‘i’ was not declared ‘constexpr’
   constexpr auto l = [i]() {
Run Code Online (Sandbox Code Playgroud)

哪个编译器正确?在我看来,这是一个GCC错误,其中lambda捕获的constexpr-ness没有正确传播到lambda上下文.

c++ lambda c++17

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

如果自定义分配器中不存在重绑定,std :: allocator_traits是否定义了rebind_alloc?

我正在尝试重新绑定我的自定义分配器类型MyAllocator<foo>,以便在basic_string类中使用,例如:

std::basic_string<char, std::char_traits<char>, MyAllocator<char>> ...

分配器被传递给上下文MyAllocator<void>,所以我需要重新绑定分配器.

从cppreference页面std::allocator_traits,http://en.cppreference.com/w/cpp/memory/allocator_traits :

成员别名模板:

rebind_alloc<T>: Alloc::rebind<T>::other如果存在,否则Alloc<T, Args>如果此Alloc是Alloc<U, Args>

我的自定义分配器实现allocator_traits,但没有定义重新绑定结构(这似乎不是实现的要求allocator_traits).我对文档的理解是它allocator_traits应该理解rebind_alloc.但是,如果我尝试调用rebind_alloc我的自定义分配器类型:

template<typename T>
using RebindAlloc =
  typename std::allocator_traits<MyAllocator<void>>::template rebind_alloc<T>;
Run Code Online (Sandbox Code Playgroud)

我尝试传递RebindAlloc<char>basic_string类型时遇到各种编译器错误:

In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/string:52:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:41: error: 
  'rebind' following the 'template' keyword does not refer to a template
  typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
Run Code Online (Sandbox Code Playgroud)

很明显,文档误导了我.我应该放弃rebind_alloc并在自定义分配器中实现重新绑定,还是有正确的方法来执行此操作allocator_traits? …

c++ templates allocator c++11

7
推荐指数
1
解决办法
1475
查看次数

带有自定义分配器的std :: promise似乎使用global new

上下文:我正在编写一个库,该库为想要自定义内存分配以实现实时性能的用户提供了许多stdlib数据结构中的自定义分配器。

我想与std::promise和使用自定义分配器std::future。我的理解是,当分配器传递给时std::promise,其future对象也使用该自定义分配器。

我的测试将覆盖new和delete全局变量,以跟踪调用默认操作符的次数。我还实现了一个自定义分配器,该分配器使用mallocfree但使用不同的状态来计数分配/取消分配(在实际示例中,它将被实时安全分配器代替)。

看来,当我要求std::promise::set_value使用“大”对象时,将调用全局运算符new和delete,即使promise使用了自定义分配器构造了全局操作符也是如此。

这是一个基本的例子。(为简便起见,删除了分配器样板,您可以在Gist上看到完整的可编译版本:https//gist.github.com/jacquelinekay/a4a1a282108a55d545a9

struct Foo {
  std::vector<int, InstrumentedAllocator<int>> bar;
};

int main(int argc, char ** argv) {
  (void) argc;
  (void) argv;
  InstrumentedAllocator<void> alloc;

  std::promise<Foo> promise_(std::allocator_arg, alloc);
  std::shared_future<Foo> future_ = promise_.get_future().share();

  // Start a thread that blocks for a few ms and sets the future value
  std::thread result_thread(
    [&promise_]() {
      Foo result;
      result.bar.push_back(1);
      result.bar.push_back(2);
      result.bar.push_back(3);
      // test_init starts counting …
Run Code Online (Sandbox Code Playgroud)

future allocator promise c++11

5
推荐指数
1
解决办法
317
查看次数

调用指向成员函数后,noexcept运算符失败

这个MWE可能看似人为,但失败的static_assert仍然令人惊讶:

#include <utility>

struct C {
  void f() noexcept { }
  using F = void(C::*)();

  static constexpr F handler() noexcept {
    return &C::f;
  }

  void g() noexcept(noexcept((this->*handler())())) {
  }
};

int main() {
  static_assert(noexcept(std::declval<C>().g()));
}
Run Code Online (Sandbox Code Playgroud)

Wandbox链接:https://wandbox.org/permlink/a8HSyfuyX1buGrbZ

我希望这可以用于Clang而不是GCC,因为它们在运算符noexcept的上下文中对"this"的处理方式不同.

c++ clang noexcept

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

标签 统计

c++ ×3

allocator ×2

c++11 ×2

c++17 ×1

clang ×1

future ×1

lambda ×1

noexcept ×1

promise ×1

templates ×1