我们有以下便利功能,可以从地图中获取值,或者如果找不到键,则返回后备默认值.
template <class Collection> const typename Collection::value_type::second_type&
FindWithDefault(const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return value;
}
return it->second;
}
Run Code Online (Sandbox Code Playgroud)
这个函数的问题是它允许传递一个临时对象作为第三个参数,这将是一个bug.例如:
const string& foo = FindWithDefault(my_map, "");
Run Code Online (Sandbox Code Playgroud)
是否可以通过使用std :: is_rvalue_reference和static assert以某种方式禁止将rvalue引用传递给第三个参数?
首先,为了阐明我的目标:我使用CSCore库并使用WasapiLoopbackCapture该类捕获背景音频,我打算将其用作System.Speech.Recognition识别引擎的实时输入.该类将数据输出到.WAV文件或Stream.然后我尝试这样做:
private void startButton_Click(object sender, EventArgs e)
{
_recognitionEngine.UnloadAllGrammars();
_recognitionEngine.LoadGrammar(new DictationGrammar());
LoadTargetDevice();
StartStreamCapture(); // Here I am starting the capture to _stream (MemoryStream type)
_stream.Position = 0; // Without setting this, I get a stream format exception.
_recognitionEngine.SetInputToWaveStream(_stream);
_recognitionEngine.RecognizeAsync(RecognizeMode.Multiple);
}
Run Code Online (Sandbox Code Playgroud)
结果是我没有得到异常,但我也没有得到SpeechRecognized或SpeechDetected事件被触发.我怀疑这是因为System.Speech.Recognition程序集不支持实时流.我在网上搜索,有人报告实施自定义Stream类型作为解决方法,但我无法按照帖子上的说明进行操作,这些说明不明确(请参阅Dexter Morgan的回复).
我知道这个问题最好通过使用不同的库或替代方法来解决,但我想知道如何专门做这个临时实现,主要是出于知识目的.
谢谢!
假设我有一个写入a的线程Aatomic_int x = 0;,使用x.store(1, std::memory_order_relaxed);.没有任何其他同步方法,在其他线程看到这个之前需要多长时间,使用x.load(std::memory_order_relaxed);?x根据标准给出的C/C++内存模型的当前定义,写入的值是否可能完全保持线程局部?
我手边的实际案例是线程Batomic_bool频繁读取以检查是否必须退出的情况; 另一个线程,在某些时候,写入true给这个bool,然后调用线程B上的join().显然我不介意在线程B甚至可以看到atomic_bool被设置之前调用join(),我也不介意线程在调用join()之前,B已经看到了更改并退出了执行.但我想知道:memory_order_relaxed在双方使用,是否可以调用join()并阻止"永远",因为更改永远不会传播到线程B?
我联系了Mark Batty(数学验证并随后修复C++内存模型要求的大脑).最初是关于别的东西(原来是cppmem和他的论文中的一个已知的错误;幸运的是我没有完全愚弄自己,并借此机会向他询问这个问题;他的回答是:
问:从理论上讲,这样的商店[memory_order_relaxed没有(任何跟随)释放操作]永远不会到达另一个线程吗?
马克:从理论上讲,是的,但我认为没有观察到这一点.
问:换句话说,松散的商店没有任何意义,除非你将它们与一些发布操作结合(并在另一个线程上获取),假设你想要另一个线程看到它?
Mark:几乎所有的用例都使用release和acquire,是的.
遵循FetchContent文档,例如使用类似的东西
FetchContent_Declare(
gitache_package_libcwd_r
GIT_REPOSITORY "https://github.com/CarloWood/libcwd.git"
GIT_TAG "master"
)
FetchContent_MakeAvailable(
gitache_package_libcwd_r
)
Run Code Online (Sandbox Code Playgroud)
源代码被克隆到${CMAKE_BINARY_DIR}/_deps/gitache_package_libcwd_r-src/.
我怎样才能让它把源代码放在其他地方,比如/opt/gitache/libcwd_r/src/gitache_package_libcwd_r(就像我使用ExternalProjecta PREFIXof时那样/opt/gitache/libcwd_r)?
我的编译器(g ++和clang)都不会编译它:
#include <vector>
struct A {
friend bool operator!=(A const& a1, A const& a2) { return false; }
};
int main()
{
std::vector<A> v1, v2;
return (v1 != v2);
}
Run Code Online (Sandbox Code Playgroud)
错误是!(*__first1 == *__first2)stl_algobase.h 中的某个地方无效.
换句话说,它完全忽略了现有的运算符!= A.不用说,如果我定义一个operator==然后它编译和工作.
这是根据标准应该如何?
如果是这样,为什么?
我正在echo server使用套接字和系统调用编写自己的程序。我习惯epoll同时与许多不同的客户端一起工作,并且对客户端完成的所有操作都是非阻塞的。当服务器打开并且什么都不做时,它在epoll_wait. 现在我想添加使用信号关闭服务器的可能性。例如,我在 中启动服务器bash terminal,然后按ctrl-c,服务器以某种方式处理SIGINT. 我的计划是使用signalfd. 我使用以下代码创建新的signalfd并将其添加到epoll实例中:
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGINT);
signal_fd = signalfd(-1, &mask, 0);
epoll_event event;
event.data.fd = signal_fd;
event.events = EPOLLIN;
epoll_ctl(fd, EPOLL_CTL_ADD, signal_fd, &event);
Run Code Online (Sandbox Code Playgroud)
然后我希望,当我在epoll等待并按下时ctrl-c,事件epoll发生,它唤醒,然后我使用以下代码处理信号:
if (events[i].data.fd == signal_fd)
{
//do something
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
虽然实际上服务器只是停止而不处理信号。我做错了什么,解决我的问题的正确方法是什么?如果我没有正确理解信号,应该使用的地方是什么signalfd?
我知道在线程2中的发布存储操作和线程1中的获取加载操作之间将发生同步关系,即使该加载操作不直接读取线程2存储的值,前提是存在发布存储操作与实际读取的存储之间的"释放顺序",只要:
但是,我没有看到任何理由为什么在实际读取的存储位于不同的线程中时也不可能同步,前提是发布存储操作仍然发生 - 在存储之前实际上正在阅读.标准明确不允许这样做吗?如果是这样,那么标准是否可能不完整是因为它有意义并且所有现有硬件都会有这样的同步?
考虑以下示例,其中a,x和y是使用0初始化的原子int.
线程1:
k = y.load(memory_order_acquire);
x.store(1, memory_order_relaxed);
Run Code Online (Sandbox Code Playgroud)
线程2:
m = x.load(memory_order_relaxed);
y.store(2, memory_order_release);
a.store(2, memory_order_release);
Run Code Online (Sandbox Code Playgroud)
线程3:
n = a.load(memory_order_acquire);
y.store(3, memory_order_relaxed);
Run Code Online (Sandbox Code Playgroud)
问题是,有可能我们最终得到k = 3,m = 1和n = 2?
如果线程2中的存储到y和线程3中的存储到y之间没有释放序列,那么在线程2中的释放存储到y之间没有同步 - 并且在线程1中没有与y的获取读取,因此线程2中的x的负载不必在线程1中存储到x之前发生,使得k,m和n的期望结果成为可能.
但是,如果有是商店至y在线程2和存储到y在螺纹3之间的释放顺序则是一个进行同步-与释放存储到y在线程2和获取在线程1读出用Y之间因此,线程2中x的负载需要在线程1中存储到x之前发生,从而无法获得所需的k,m和n结果.请注意,如果a的存储/加载不在那里,我们只是在线程2的末尾做了值为3到y的松弛存储,那么情况就是如此(所以k = 3和m =永远不会发生1).
在这种情况下,值3到y的存储发生在线程3中,但是存在使用原子变量a的释放 - 获取同步; 因此,如果n = 2,那么在值2到y的释放存储和值3到y的松弛存储之间存在先发生关系.并不意味着存在是一个释放顺序和结果,其中k = 3,M = 1且n = 2永远不会发生?
编辑
请注意,运行以下代码段:
int main()
{
atomic_int a = 0;
atomic_int x = 0;
atomic_int y = 0; …Run Code Online (Sandbox Code Playgroud) 我很惊讶 boost::date_time 似乎可以写入它无法读取的日期/时间字符串。
考虑以下示例代码:
#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>
#include <locale>
class PointTime : public boost::local_time::local_date_time {
typedef boost::local_time::local_time_input_facet input_facet_t;
typedef boost::local_time::local_time_facet output_face_t;
public:
static input_facet_t const s_input_facet;
static output_face_t const s_output_facet;
static std::locale const s_input_locale;
static std::locale const s_output_locale;
public:
PointTime(std::string const& str);
};
PointTime::input_facet_t const PointTime::s_input_facet("%Y-%m-%dT%H:%M:%S%q", 1);
PointTime::output_face_t const PointTime::s_output_facet("%Y-%m-%dT%H:%M:%S%q",
boost::local_time::local_time_facet::period_formatter_type(),
boost::local_time::local_time_facet::special_values_formatter_type(),
boost::local_time::local_time_facet::date_gen_formatter_type(),
1);
std::locale const PointTime::s_input_locale(std::locale::classic(), &PointTime::s_input_facet);
std::locale const PointTime::s_output_locale(std::locale::classic(), &PointTime::s_output_facet);
PointTime::PointTime(std::string const& str) : boost::local_time::local_date_time(boost::local_time::not_a_date_time)
{
std::istringstream is(str);
is.imbue(s_input_locale);
is >> *this;
std::string s;
is >> s; …Run Code Online (Sandbox Code Playgroud) 我编写了一个线程池,其中包含尽可能多的线程(备用核心),以避免上下文切换。每当需要执行新任务时,该任务就会添加到无锁环形缓冲区中,供线程池中的线程使用。每次添加新任务时,我当前都会调用sem_post。
我的基准测试显示,sem_post当有线程等待信号量时,调用需要 10 微秒。有些调用只需要 50 纳秒(这可能意味着完全在用户空间中可以确定没有可以唤醒的线程),但 350 +/- 30 纳秒也是一个常见的值。
这个问题是关于一个或多个线程无事可做并且正在等待信号量的情况。
我一点也不高兴,在这种情况下,调用者(试图唤醒一个新线程)在sem_post.
是否有一种更快的方法(从调用者的角度来看)来唤醒休眠线程?我可以忍受 10 微秒的延迟,直到新线程最终开始运行,但唤醒线程不应延迟那么多。
我可以找到的相关问题(但不回答我的问题)是
请注意,信号量似乎是在 futex 之上实现的。我认为 futex 是 Linux 上最快的方法?也许使用信号或中断更快?
经过两三天的尝试,我不得不放弃并编写了一个“最小”测试用例,希望能够证明该问题。
我需要的是一种将字符串文字(作为不带引号的宏参数传递)转换为可在 constexpr 环境中访问的字符串(用前缀连接)的方法(请参阅https://wandbox.org/permlink/Cr6j6fXemsQRycHI真实代码( tm));这意味着,它们(宏参数)应该被字符串化,然后转换为类型(例如 template <... 'h', 'e', 'l', 'l', 'o', ...>)或转换为static constexpr array<char, N>传递的唯一类型的 a (例如 template <... A<1> ...>,其中A<1>::strastatic constexpr array<char, 6>包含内容'h', 'e', 'l', 'l', 'o', '\0'.
我强烈喜欢后者,只有当后者不可能时才选择前者。
为了在简短的测试用例中演示确切的问题/要求,我提出了以下内容:
一些标题...
#include <array>
#include <tuple>
#include <cassert>
#include <string>
#include <iostream>
Run Code Online (Sandbox Code Playgroud)
然后为了演示最终结果应该如何表现:
template<int I>
struct A;
template<>
struct A<0>
{
static constexpr auto str = std::to_array("abc"); // The string-literal "abc" may NOT appear here.
// …Run Code Online (Sandbox Code Playgroud)