gpt4 book ai didi

c++ - 如何让编译器忽略这个计算结果为 false 的 if-constexpr?

转载 作者:搜寻专家 更新时间:2023-10-31 00:06:24 24 4
gpt4 key购买 nike

我正在编写一个宏,当它被用来包装函数调用时,如下所示:macro(function()) , 返回 std::optional<T> ,其中 T 是函数的返回值。到目前为止它有效,但我在尝试让它返回 std::optional<bool> 时遇到了问题当函数没有返回类型时(即返回 void)。

问题的核心在于,当函数没有返回类型时,编译器会尝试计算 if-constexpr 的范围,该范围的计算结果为 false。

我尝试使用两个 if-constexpr 和一个与 else。我尝试内联所有内容并将其展开几行。我尝试用常量文字替换编译器计算的 constexpr 常量。到目前为止没有任何效果。

我现在的宏看起来像这样:

#ifndef troy
#define troy(body)[](){\
constexpr auto inner_type_is_void=std::is_same<decltype(body), void>::value;\
using inner_type=std::conditional<inner_type_is_void,bool,decltype(body)>::type;\
try{\
if constexpr (inner_type_is_void) {(body); return std::optional<inner_type>{true};}\
if constexpr (!inner_type_is_void) {return std::optional<inner_type>{(body)};}\
} catch (...){\
return std::optional<inner_type>{};\
}\
}()
#endif

我是这样使用它的:

{
auto a=troy(f());
if (!a){
std::cout << "fail" << std::endl;
} else{
std::cout << "success: " << *a << std::endl;
}
}

它在 f 返回值时起作用,但在没有返回值时给出编译器错误。此编译器错误是:no matching function for call to ‘std::optional<bool>::optional(<brace-enclosed initializer list>)’在 if-constexpr 计算结果为 false 的那一行。

最佳答案

为了避免为 if constexpr 进行实例化,您需要一个实际具有实例化的上下文:您需要某种模板。在模板之外,if constexpr 没有任何魔力。

一如既往,解决方案是将所有内容都包装在 lambda 中。现在,您正在为实际的函数体使用内嵌的 body。相反,您可以使用 lambda:

[&]() -> decltype(auto) { return body; }

然后将整个事情包装在一个立即调用的 lambda 中,该 lambda 将此 lambda 作为参数:

[](auto f){
// stuff
}([&]() -> decltype(auto) { return body; })

现在,在我标记了 //stuff 的地方,我们处于模板上下文中,我们实际上可以使用 if constexpr 来避免实例化:

[](auto f){
using F = decltype(f);
using R = std::invoke_result_t<F>;
try {
if constexpr (std::is_void_v<R>>) {
f();
return std::optional<bool>(true);
} else {
return std::make_optional(f());
}
} catch (...) {
return std::optional<std::conditional_t<std::is_void_v<R>, bool, R>>();
}
}([&]() -> decltype(auto) { return body; })

现在只需添加一堆 \ 就可以了。

关于c++ - 如何让编译器忽略这个计算结果为 false 的 if-constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57975669/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com