小编md5*_*d5i的帖子

为什么 type_identity 会产生影响?

我知道lambda对象不是std::function对象,所以我知道这是行不通的:

\n
\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}\n
Run Code Online (Sandbox Code Playgroud)\n

但如果我添加一个 type_identity 来包装它,为什么它会起作用呢?

\n
template <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\n
Run Code Online (Sandbox Code Playgroud)\n

据我所知,这两个看起来几乎相同,甚至通过了,这static_assert意味着它们与 .\n 相同std::is_same。\n但编译器并不这么认为。它告诉我,在前一个代码中,lambda 不能匹配任何函数,而后一个可以。

\n

error: no matching …

c++ templates metaprogramming

12
推荐指数
1
解决办法
1838
查看次数

OCaml格式和结构框:为什么我的输出与示例不匹配?

在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>初始示例相同的输出.有人会有任何想法如何从网页获得类似于第二个例子的输出?

io ocaml

6
推荐指数
1
解决办法
420
查看次数

将OCaml Maps扩展到可格式化的地图

我为可格式化的集合创建了一个仿函数,如下所示:

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)

ocaml map functor

6
推荐指数
1
解决办法
153
查看次数

比率乘法期间的 chrono::duration_cast 问题

我正在编写一些必须处理 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::durationstd::chrono::duration<int64_t, std::nano>. 当我尝试std::chrono::duration_cast在这两个持续时间之间进行转换时,我在任一方向上都得到了大量的截断。在调试器中跟踪这一点,我发现它与实现有关duration_cast,在 libstdc++、libc++ 和 boost::chrono 中以同样的方式失败。简而言之,要从系统表示转换为 ntp 表示,它乘以比率 8388608/1953125,并在另一个方向上乘以相反的比率。它首先乘以分子,然后除以分母。数学是正确的,但初始乘法溢出了 64 位表示并被截断,尽管实际转换(除法后)仍然可以轻松地用这些位表示。

我可以手动进行此转换,但我的问题如下:

  1. 这是实现中的错误,还是只是一个限制?
  2. 如果有限制,我是否应该意识到这会是一个问题?我没有看到任何文档似乎可以猜测这行不通。
  3. 有没有一种通用的方法来实现这一点,而不会遇到同样的问题?
  4. 应该向谁报告此事?
  5. 最后,如果当 C++20 出现时,我使用具有手动策划to_sysfrom_sys功能的 NTP 时钟,我是否可以简单地使用std::chrono::clock_cast而不必担心其他微妙的问题?

这是我用来测试这个的代码和一些示例输出:

// #define BOOST
#ifdef BOOST
#  include <boost/chrono.hpp>
#  define …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++-chrono c++20

6
推荐指数
1
解决办法
718
查看次数

使用多个上游存储库进行测试

我有一个持续构建和测试场景,我正在尝试弄清楚如何在 Jenkins 中实现,我希望有人能引导我朝正确的方向前进。

我有一个项目foo,它依赖于其他几个上游项目,bar并且baz。所有三个项目都在持续开发中,有 API 更改、随机故障等。我们希望使用上游项目的最新版本,因为它们经常根据我们的要求进行更改。

鉴于bar和的具体已知修订版baz可以与测试foo通过foo,我想要以下内容:

无论何时barbaz发生变化,我都想构建它们并foo针对它们测试构建。如果这些测试通过,我希望bar/的新版本baz成为新的“已知良好”版本。

每当foo发生变化时,我想针对bar和的最新版本进行编译bazbar如果测试通过,则的最新版本baz将成为新的“已知良好”版本。如果测试失败,我想针对bar/的最后一个“已知良好”版本进行编译baz

我们的想法是快速了解上游更改何时导致问题,并继续根据已知良好的上游版本检查项目中的更改。当上游由于上游错误而导致我们的项目失败时,我们希望继续使用最后一个已知的良好版本进行测试。当上游由于 API 更改或行为改进而导致我们的项目失败时,我们希望更新代码来处理这些问题,然后切换到这些新版本以进行将来的构建/测试。

我浏览了 Jenkins Pipeline,乍一看它可能能够处理类似的事情,但我真的不想陷入学习新 DSL(和 Groovy)的兔子洞,如果这是这样的话不太适合我们的问题。

jenkins jenkins-pipeline

6
推荐指数
1
解决办法
734
查看次数

调用带有额外参数的C函数是否可移植?

请考虑以下代码:

#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以及它如何确定函数参数和局部变量的存储位置.更重要的是,这可能不是可移植代码.但我已经看到这个习惯用法在实际代码库中多次使用.

c

2
推荐指数
1
解决办法
237
查看次数

初始化列表中的类constexpr表达式

以下代码无法与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)

如果我评论出地图,事情就好了.这是一个编译器错误,还是我在标准中缺少的一些极端情况?

c++ initialization-list constexpr c++11

0
推荐指数
1
解决办法
465
查看次数