在下面的代码示例中,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
我在 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。然而,当该行被注释掉后,代码就完成了,没有打印任何内容。