我对从async返回的策略和对象的std::async
函数行为有一些疑问.std::launch::async
std::future
在下面的代码中,主线程等待foo()
通过async
调用创建的线程完成.
#include <thread>
#include <future>
#include <iostream>
void foo()
{
std::cout << "foo:begin" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "foo:done" << std::endl;
}
int main()
{
std::cout << "main:begin" << std::endl;
{
auto f = std::async(std::launch::async, foo);
// dtor f::~f blocks until completion of foo()... why??
}
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "main:done" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我知道http://www.stdthread.co.uk/doc/headers/future/async.html说
与返回的std :: future的异步状态关联的最后一个对象的析构函数将阻塞,直到将来准备就绪.
我的问题是:
在下面的代码片段中,带有C++ 1z模式的GCC 7调用默认构造函数,但GCC/C++ 14和Clang/C++ 14,C++ 1z调用initializer-list构造函数.
此行为是否受到任何C++ 1z规范更改(可能是保证副本省略?)或GCC错误的影响?
#include <cstdio>
#include <initializer_list>
struct S {
S() { std::printf("DEF "); } // (1)
S(std::initializer_list<int> il) // (2)
{ std::printf("L=%zu ", il.size()); }
};
int main() {
S x({});
}
Run Code Online (Sandbox Code Playgroud)
输出:
我想知道为什么=
捕获默认模式禁止this
在C++ lambda表达式的捕获列表中.
那是,
[=, this]{ }; // error
[&, this]{ }; // OK
Run Code Online (Sandbox Code Playgroud)
这由C++ 11 5.1.2/8指定.
- 如果lambda-capture包含一个捕获默认值为&,则lambda-capture中的标识符不应以&开头.
- 如果lambda-capture包含一个=的capture-default,则lambda-capture不应该包含这个,并且它包含的每个标识符都应以&开头.
问:这条规则有什么理由或背景故事吗?
Java 8正式向java.io.UncheckedIOException
带有Stream API的lambda 引入JDK类库,因为lambda表达式不能声明其throws
-clause和lambda体不能抛出检查过的异常等IOException
.
使用UncheckedIOException
和Stream API 有什么成语/最佳实践?我明确抛出新UncheckedIOException
对象的条件是什么,何时应该捕获UncheckedIOException
异常?
当我使用cancel
指令(因为OpenMP 4.0)来破坏parallel for
构造中的并行循环时,GCC 5.1警告"'#pragma omp取消'内部'nowait'for construct"以用于下面的代码片段.
const int N = 10000;
int main()
{
#pragma omp parallel for
for (int i = 0; i < N; i++) {
#pragma omp cancel for // <-- here
}
}
Run Code Online (Sandbox Code Playgroud)
http://coliru.stacked-crooked.com/a/de5c52da5a16c154
对于变通方法,当我拆分为parallel
+ for
构造时,GCC会默默接受代码.
int main()
{
#pragma omp parallel
#pragma omp for
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
}
Run Code Online (Sandbox Code Playgroud)
但我不知道为什么海湾合作委员会会警告前一种情况,但该构造没有'nowait'条款.
OpenMP 4.0 API规范也表示parallel for
等于 …
我正在寻找有关引用和可变引用类型的复制/移动语义的文档。
以下代码片段显示不可变引用 ( & T
) 实现了Copy
trait 而可变引用 ( &mut T
) 没有。
struct T;
fn copyable<U>(_: U) where U: Copy {}
fn main() {
let a = &T;
copyable(a); // OK
let b = &mut T;
copyable(b);
// error: the trait `core::marker::Copy` is not implemented for the type `&mut T`
}
Run Code Online (Sandbox Code Playgroud)
但我找不到这种行为的描述。有人知道一些(非)官方文件吗?(还是我错了?)
C++ 03标准7.3.1.1 [namespace.unnamed]第1段:(和C++ 11标准也使用相似的定义)
一个不愿透露姓名的命名空间定义的行为就好像它被取代
Run Code Online (Sandbox Code Playgroud)namespace unique { /* empty body */ } using namespace unique; namespace unique { namespace-body }
为什么不简单地遵循定义?
namespace unique { namespace-body }
using namespace unique;
Run Code Online (Sandbox Code Playgroud)
附带问题:MSDN按后一种形式定义.它在技术上是否违反了标准?
在 C++20 标准库std::condition_variable_any::wait()
家族中支持std::stop_token
广义线程取消,但std::condition_variable
不支持。
R6 中的新功能
- 用户
condition_variable_any
而不是consition_variable
避免所有可能的竞争、死锁和意外的未定义行为。
我认为下面的代码安全模拟condition_variable::wait()
与stop_token
消除。我错过了什么?是否有微妙的边缘情况?
template<class Lock, class Predicate>
bool cv_wait_with_stoken(
std::condition_variable& cv, Lock& lock, std::stop_token stoken, Predicate pred)
{
std::stop_callback callback{ stoken, [&cv]{ cv.notify_all(); } };
while (!stoken.stop_requested()) {
if (pred())
return true;
cv.wait(lock);
}
return pred();
}
Run Code Online (Sandbox Code Playgroud) 在 C++23 中,lambda 表达式支持显式对象参数(也称为“推导 this”)。我在[expr.prim.lambda]/p5处捕获时发现了 lambda 的奇怪限制。
给定具有 lambda 捕获的 lambda,lambda 函数调用运算符(可能从函数调用运算符模板实例化)的显式对象参数(如果有)的类型应为:
- 闭合类型,
- 从闭包类型派生的类类型,或者
- 对可能符合 cv 资格的此类类型的引用。
[示例2:
Run Code Online (Sandbox Code Playgroud)struct C { template <typename T> C(T); }; void func(int i) { int x = [=](this auto&&) { return i; }(); // OK int y = [=](this C) { return i; }(); // error int z = [](this C) { return 42; }(); // OK }
--结束示例]
问题:为什么仅使用 capture 的 lambda 有这样的限制?是否存在执行问题?