考虑这个将变量声明为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上下文.
我正在尝试重新绑定我的自定义分配器类型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? …
上下文:我正在编写一个库,该库为想要自定义内存分配以实现实时性能的用户提供了许多stdlib数据结构中的自定义分配器。
我想与std::promise和使用自定义分配器std::future。我的理解是,当分配器传递给时std::promise,其future对象也使用该自定义分配器。
我的测试将覆盖new和delete全局变量,以跟踪调用默认操作符的次数。我还实现了一个自定义分配器,该分配器使用malloc,free但使用不同的状态来计数分配/取消分配(在实际示例中,它将被实时安全分配器代替)。
看来,当我要求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) 这个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"的处理方式不同.