gpt4 book ai didi

c++ - 范围内的模板变量或模板 typedef

转载 作者:行者123 更新时间:2023-11-30 05:03:51 25 4
gpt4 key购买 nike

为什么不能在范围内声明模板变量或模板 typedef?

我想像这样用c++17写一段代码

auto foo = [](auto fun, auto... x) {
template <typename T>
using ReturnType = std::invoke_result_t<fun, T>;

if constexpr (!(std::is_same_v<void, ReturnType<decltype(x)>> || ... ||
false)) {
return std::tuple<ReturnType<decltype(x)>...>(fun(x)...);
} else {
(fun(x), ...);
return;
}
};

这段代码定义了一个函数foo它需要一个函数 fun和一堆论点x... .如果所有返回类型 fun(x)不是 void然后返回一个结果元组。如果至少一种返回类型是 void然后调用所有函数但返回 void .

在这个简单的例子中,我当然可以替换 ReturnType<decltype(x)>decltype(fun(x)) ,但在我的用例中,实际类型要复杂得多,上面的代码仅作为动机。

另外,我讨厌写作 ReturnType<decltype(x)> .我更喜欢写 ReturnType(x) ,但这可能是不可能的。


我不喜欢的解决方案: 在函数外定义模板 typedef 为

template<typename Fun, typename T>
using ReturnType = std::invoke_result_t<Fun,T>;

然后在函数中使用

ReturnType<decltype(fun),delctype(x)>

时间越来越长,我必须将每个本地类型都作为模板参数。

最佳答案

代码实际上更简单,没有引入任何助手:

if constexpr ((!std::is_void_v<decltype(fun(x))> && ...)) {
return std::tuple(fun(x)...);
} else {
(fun(x), ...);
}

&&||具有空包的默认值(分别为 truefalse),因此您不必将它们转换为一元运算符。而且你不需要 invoke_result_t因为你只是直接打电话。即使你这样做了:

using F = decltype(fun);
if constexpr ((!std::is_void_v<std::invoke_result_t<F, decltype(x))> && ...)) {
return std::tuple(std::invoke(fun, x)...);
} else {
(fun(x), ...);
}

不久。


也就是说,我发现这个构造不是很有用 - 考虑到您对 void 得到的结果截然不同和非 void个案。也许f(x)仍然是 X但是f(y)void ,我们会得到 foo(x,x)正在tuple<X,X>但是foo(x,y)正在void ?很难编码。

我建议不要删除所有返回类型,而是解决损坏的类型。如:

struct Void { };

template <typename F, typename... Args,
typename R = std::invoke_result_t<F, Args...>,
REQUIRES(std::is_void_v<R>)>
Void invoke_void(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
return Void{};
}

template <typename F, typename... Args,
typename R = std::invoke_result_t<F, Args...>,
REQUIRES(!std::is_void_v<R>)>
R invoke_void(F&& f, Args&&... args) {
return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}

现在,我们可以随时调用函数并返回它:

auto foo = [](auto fun, auto... x) {
return std::tuple(invoke_void(fun, x)...);
};

关于c++ - 范围内的模板变量或模板 typedef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49214517/

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