在重构一些遗留代码时,我遇到了要在 STL 算法中使用的谓词的这种传统实现:
template<bool b>
struct StructPred {
bool operator()(S const & s) { return s.b == b; }
};
Run Code Online (Sandbox Code Playgroud)
我累了,撞到了鲍尔默峰,所以我不小心把它改写成了这样的 lambda,这看起来很自然,也很有效:
template<bool b>
auto lambda_pred = [] (S const & s) { return s.b == b; };
Run Code Online (Sandbox Code Playgroud)
后来我意识到我从未见过这样的模板 lambda。我在 cppreference 或 stackoverflow 上找不到任何类似的东西。生成模板 lambda 的规范方法似乎是将它们包装在模板结构或模板函数中。C++20 为 lambda 引入了命名模板参数,但这是一种不同的语法(在捕获括号之后)。
现在我的问题是:这是合法的语法吗?它在任何地方都有记录吗?它甚至是 lambda 还是其他什么?与包装替代品相比,是否有任何影响或副作用?为什么每个人都推荐包装器实现呢?我错过了一些明显的东西吗?
下面和Godbolt 上的完整工作测试代码。为了确保我还添加了一个类型模板参数版本。MSVC、GCC 和 clang 对这段代码很满意。
#include <vector>
#include <algorithm>
struct S {
bool b = false;
};
// classic function object
template<bool b>
struct StructPred { …Run Code Online (Sandbox Code Playgroud) 这些方法的实现对我来说似乎很简单,它们可以使用std::string并且std::string_view更易于互换.毕竟,std::string_view具有使对象处于与这些方法相同状态的构造函数.可以解决丢失的方法,如下所示:
std::string s {"abcd"};
std::string_view v {s.c_str()};
std::cout << "ctor: " << v << std::endl; // "abcd"
v = {s.c_str() + 1, 2};
std::cout << "assign: " << v << std::endl; // "bc"
v = {nullptr}; // or even v = {};
std::cout << "clear: " << v << std::endl; // ""
Run Code Online (Sandbox Code Playgroud)
那么,在标准中不包括这两种明显方法的原因是什么?
更新:你的评论中的一个普遍问题似乎是"有什么意义?",所以我会给你一些背景信息.我正在解析一个大字符串,结果是一个子串结构.结果结构是字符串视图的自然候选者,因此我不必复制所有那些甚至重叠的字符串.部分结果是映射到字符串视图,因此我可能需要在获取密钥时将它们构造为空,并在获取值时稍后填充它们.在解析时,我需要跟踪中间字符串,这涉及更新和重置它们.现在它们也可以被字符串视图替换,这就是我在那些缺少的函数上发生的事情.当然我可以继续使用字符串或用普通的旧ptr-ptr或ptr-size对替换它们,但这正是std::string_view为了什么,对吧?
我需要使用 Windows 加密 API 方法验证已签名的 JAR 文件。我对加密和签名问题只有基本的了解。我也是那些加密 API(WinCrypt、Bcrypt、Ncrypt)的新手。验证文件哈希不是问题,但签名部分阻止了我。
多亏了 OpenSSL、PKCS7 RFC ( https://tools.ietf.org/html/rfc2315 ) 和各种其他来源,我才能够找出 JAR 中包含的 META-INF/LOCALSIG.DSA 的实际文件内容。但是经过两周的挖掘、反复试验,我仍然被卡住,不知道还能尝试什么。
OpenSSL 有很好的命令openssl smime -verify -inform der -in LOCALSIG.DSA -content LOCALSIG.SF -noverify,它完全符合我的要求。不幸的是,我在 Windows API 中找不到这样的高级命令。
我已经尝试使用VerifySignature来自所有三个 API 的函数系列,但是我需要为它们提供公钥,并且我没有使用任何ImportKey函数。因此,我尝试使用CryptDecodeObjectEx,手动剖析 ASN1 格式,以便将各个部分作为 BLOB 传递给 API 函数。虽然我在这方面取得了一些成功,但我再次陷入困境,因为我无法弄清楚如何解析集合。我不想从头开始编写自己的 ASN1 解析器...
那么,如何将 PKCS7 签名文件与 Windows 加密 API 一起使用?
我想使用 OpenSSL 可能会更容易,但是我必须说服我的雇主为了这个目的将 OpenSSL 添加到我们的代码库中......
更新:LOCALSIG.DSA 文件包含签名者证书和 LOCALSIG.SF 文件的签名散列。这可以使用openssl pkcs7 -inform der -print_certs -text -in LOCALSIG.DSA或进行验证openssl cms …
我正在尝试在多个产品之间共享一个属性,默认情况下未设置该属性。除了一种产品,我想将其设置为一个值。
所以在 shared.wxi 中:
<Include>
<Property Id="MYPROP" Secure="yes"></Property>
</Include>
Run Code Online (Sandbox Code Playgroud)
在 product.wxs 中:
<Wix>
<Product>
<?include ..\shared\shared.wxi?>
<SetProperty Id="MYPROP" Value="1" After="InstallInitialize"/>
</Product>
</Wix>
Run Code Online (Sandbox Code Playgroud)
但是我们的构建系统抱怨:
error LGHT0094 : Unresolved reference to symbol 'WixAction:InstallUISequence/InstallInitialize' in section 'Product:{583365A4-93C2-434A-BCD8-8A1035DF2AC7}'
Run Code Online (Sandbox Code Playgroud)
我什至不确定After="InstallInitialize"(或 Before=...) 是否正确,我只想在包含之后但在考虑其他任何事情之前设置此产品的属性。此外,我对整个 WIX 系统几乎一无所知,我只是想在知识渊博的同事休假期间快速修复某些问题。
更新 - 现在我尝试了这个而不是SetProperty,但仍然得到同样的错误:
<CustomAction Id="CA_SETMYPROP" Property="MYPROP" Value="1" />
<InstallUISequence>
<Custom Action="CA_SETMYPROP" Before="InstallInitialize" />
</InstallUISequence>
Run Code Online (Sandbox Code Playgroud)
更新 2 - 现在我替换InstallUISequence了InstallExecuteSequence它并且它做了我想要的。有关解释和替代解决方案,请参阅 Rob Mensching 的回答。
<CustomAction Id="CA_SETMYPROP" Property="MYPROP" Value="1" />
<InstallExecuteSequence>
<Custom Action="CA_SETMYPROP" Before="InstallInitialize" />
</InstallExecuteSequence>
Run Code Online (Sandbox Code Playgroud)