我知道lambda对象不是std::function对象,所以我知道这是行不通的:
\ntemplate <typename ...args_t>\nvoid func(std::function<void(args_t...)> function_, args_t ...args){\n /// do something here\n}\n\nvoid test() {\n func([](int a){ }, 1);\n}\nRun Code Online (Sandbox Code Playgroud)\n但如果我添加一个 type_identity 来包装它,为什么它会起作用呢?
\ntemplate <typename T>\nstruct type_identity {\n using type = T;\n};\ntemplate <typename T>\nusing type_identity_t = typename type_identity<T>::type;\n\ntemplate <typename... args_t>\nvoid func_wrapped(type_identity_t<std::function<void(args_t...)>> function_, \n args_t ...args) {\n static_assert(std::is_same< std::function<void(args_t...)>,\n type_identity_t<std::function<void(args_t...)>>\n >::value,\n "different type");\n /// do something here\n}\n\nvoid test() {\n func_wrapped([](int a){ }, 1);\n}\n\nRun Code Online (Sandbox Code Playgroud)\n据我所知,这两个看起来几乎相同,甚至通过了,这static_assert意味着它们与 .\n 相同std::is_same。\n但编译器并不这么认为。它告诉我,在前一个代码中,lambda 不能匹配任何函数,而后一个可以。
error: no matching …
在OCaml网站上的" 使用格式模块"页面上有一个示例,它提供了结构和打包hov框之间差异的示例.我试图复制这个例子.(我使用的是OCaml 3.12.1.)
通过以下输入:
Format.printf "@[<hov 2>(---@\n@[<hov 2>(---@\n@[<hov 2>(---@,)@]@,)@]@,)@]@\n"
Run Code Online (Sandbox Code Playgroud)
我得到了预期的输出:
(---
(---
(---)))
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚的是如何将页面输出归结为"结构框":
(---
(---
(---
)
)
)
Run Code Online (Sandbox Code Playgroud)
我不确定哪个Format.printf标识符映射到这些框,所以我尝试了几种变体:
Format.printf "@[<hv 2>(---@\n@[<hv 2>(---@\n@[<hv 2>(---@,)@]@,)@]@,)@]@\n"
Format.printf "@[<2>(---@\n@[<2>(---@\n@[<2>(---@,)@]@,)@]@,)@]@\n"
Format.printf "@[<b 2>(---@\n@[<b 2>(---@\n@[<b 2>(---@,)@]@,)@]@,)@]@\n"
Run Code Online (Sandbox Code Playgroud)
但是上面的所有内容都给出了与<hov 2>初始示例相同的输出.有人会有任何想法如何从网页获得类似于第二个例子的输出?
我为可格式化的集合创建了一个仿函数,如下所示:
module type POrderedType =
sig
type t
val compare : t -> t -> int
val format : Format.formatter -> t -> unit
end
module type SET =
sig
include Set.S
val format : Format.formatter -> t -> unit
end
module MakeSet (P : POrderedType) : SET with type elt = P.t
Run Code Online (Sandbox Code Playgroud)
实现这一点很简单:
module MakeSet (P : OrderedType) =
struct
include Set.Make(P)
let format ff s =
let rec format' ff = function
| [] -> ()
| [v] …Run Code Online (Sandbox Code Playgroud) 我正在编写一些必须处理 NTP 时间的代码。我决定用 来代表他们std::chrono::duration,我希望这能让我的时间数学更容易做。
NTP 时间由无符号 64 位整数表示,高 32 位为自纪元以来的秒数,低 32 位为小数秒。纪元日期是 1900 年 1 月 1 日,但这与我在这里处理的问题是一个单独的问题,而且我已经知道如何处理这个问题。对于我正在使用的示例,为了使数学更简单,假设纪元为 1970 年 1 月 1 日。
持续时间的表示很简单:std::chrono::duration<std::uint64_t, std::ratio<1, INTMAX_C(0x100000000)>>。问题在于当我尝试在 NTP 时间和系统时钟之间进行转换时。
在我的系统上,std::chrono::system_clock::duration是std::chrono::duration<int64_t, std::nano>. 当我尝试std::chrono::duration_cast在这两个持续时间之间进行转换时,我在任一方向上都得到了大量的截断。在调试器中跟踪这一点,我发现它与实现有关duration_cast,在 libstdc++、libc++ 和 boost::chrono 中以同样的方式失败。简而言之,要从系统表示转换为 ntp 表示,它乘以比率 8388608/1953125,并在另一个方向上乘以相反的比率。它首先乘以分子,然后除以分母。数学是正确的,但初始乘法溢出了 64 位表示并被截断,尽管实际转换(除法后)仍然可以轻松地用这些位表示。
我可以手动进行此转换,但我的问题如下:
to_sys和from_sys功能的 NTP 时钟,我是否可以简单地使用std::chrono::clock_cast而不必担心其他微妙的问题?这是我用来测试这个的代码和一些示例输出:
// #define BOOST
#ifdef BOOST
# include <boost/chrono.hpp>
# define …Run Code Online (Sandbox Code Playgroud) 我有一个持续构建和测试场景,我正在尝试弄清楚如何在 Jenkins 中实现,我希望有人能引导我朝正确的方向前进。
我有一个项目foo,它依赖于其他几个上游项目,bar并且baz。所有三个项目都在持续开发中,有 API 更改、随机故障等。我们希望使用上游项目的最新版本,因为它们经常根据我们的要求进行更改。
鉴于bar和的具体已知修订版baz可以与测试foo通过foo,我想要以下内容:
无论何时bar或baz发生变化,我都想构建它们并foo针对它们测试构建。如果这些测试通过,我希望bar/的新版本baz成为新的“已知良好”版本。
每当foo发生变化时,我想针对bar和的最新版本进行编译baz。bar如果测试通过,则的最新版本baz将成为新的“已知良好”版本。如果测试失败,我想针对bar/的最后一个“已知良好”版本进行编译baz。
我们的想法是快速了解上游更改何时导致问题,并继续根据已知良好的上游版本检查项目中的更改。当上游由于上游错误而导致我们的项目失败时,我们希望继续使用最后一个已知的良好版本进行测试。当上游由于 API 更改或行为改进而导致我们的项目失败时,我们希望更新代码来处理这些问题,然后切换到这些新版本以进行将来的构建/测试。
我浏览了 Jenkins Pipeline,乍一看它可能能够处理类似的事情,但我真的不想陷入学习新 DSL(和 Groovy)的兔子洞,如果这是这样的话不太适合我们的问题。
请考虑以下代码:
#include <stdio.h>
typedef int (*addif_fn_t) (int, int, int);
int add (int a, int b) {
return a + b;
}
int addif (int a, int b, int cond) {
return cond ? (a + b) : 0;
}
int main() {
addif_fn_t fn;
fn = addif;
printf("addif:\t%d %d\n", fn(1, 2, 1), fn(1, 2, 0));
fn = (addif_fn_t)add;
printf("add:\t%d %d\n", fn(1, 2, 1), fn(1, 2, 0));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在使用标准C调用约定的任何Intel计算机上,这会导致:
addif: 3 0
add: 3 3
Run Code Online (Sandbox Code Playgroud)
问题是:这个成语有多便携?C允许调用一个参数多于它接受的函数吗?
我的猜测是它完全取决于ABI以及它如何确定函数参数和局部变量的存储位置.更重要的是,这可能不是可移植代码.但我已经看到这个习惯用法在实际代码库中多次使用.
以下代码无法与g ++ 4.8.2链接:
#include <map>
struct Foo
{
constexpr static int foo = 1;
};
static std::map<int, int> map {{1, Foo::foo}};
int main()
{
return Foo::foo;
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
g++ -std=c++11 -o foo foo.cc
/tmp/ccZXCwiK.o: In function `__static_initialization_and_destruction_0(int, int)':
foo.cc:(.text+0x51): undefined reference to `Foo::foo'
Run Code Online (Sandbox Code Playgroud)
如果我评论出地图,事情就好了.这是一个编译器错误,还是我在标准中缺少的一些极端情况?