小编Igo*_*hov的帖子

C++ 中 if/else 分支的编译时消除

在下面的代码示例中,if语句依赖于bool模板参数,它是一个编译时常量。编译器以不同的方式处理此代码:

  • MSVC 因链接错误而失败(这是我所期望的),因为else分支中的模板函数缺乏true模板参数值的专业化(即使它从未被调用)。

  • GCC 和 Clang 编译时都没有问题,并且运行时行为是正确的。这显然是因为它们if在编译时评估语句并在链接之前删除未使用的分支。

问题是哪种行为符合标准(或者它是未定义的行为并且两者都以自己的方式正确)?

#include <iostream>

template<const bool condition>
struct Struct
{
    void print()
    {
        if (condition)
        {
            std::cout << "True\n";
        }
        else
        {
            printIfFalse();
        }
    }

private:
    void printIfFalse();
};

template <>
void Struct<false>::printIfFalse()
{
    std::cout << "False\n";
}

int main()
{
    Struct<true> withTrue{};
    withTrue.print();

    Struct<false> withFalse{};
    withFalse.print();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ templates compiler-optimization template-specialization language-lawyer

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

Seq.iter 无法迭代使用 seq.collect 和序列表达式创建的序列

我在 F# 代码中遇到了一个错误,我已将其简化为以下最小再现序列,但现在我不明白为什么它会这样工作。

let duplicate element =
    [ element; element ]

let passThrough (sq: seq<_>) =
    use it = sq.GetEnumerator ()
    seq {
        while (it.MoveNext ()) do
            yield it.Current
    }

[<EntryPoint>]
let main _ =
    [0; 1]
    |> Seq.collect (duplicate)
    (* |> Seq.toArray // When uncommented - works as expected. *)
    |> passThrough
    |> Seq.iter (fun i -> printf $"{i} ")
    0
Run Code Online (Sandbox Code Playgroud)

Seq.toArray取消注释该调用时,它会产生我期望的结果,即迭代序列管道并打印0 0 1 1。然而,当该行被注释掉后,代码就完成了,没有打印任何内容。

f#

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