Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 作用域中的模板变量或模板类型定义_C++_Templates_C++17 - Fatal编程技术网

C++ 作用域中的模板变量或模板类型定义

C++ 作用域中的模板变量或模板类型定义,c++,templates,c++17,C++,Templates,C++17,为什么不能在作用域内声明模板变量或模板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)>> || ...

为什么不能在作用域内声明模板变量或模板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;
  }
};
然后在函数中使用

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

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

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

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


这就是说,我发现这个构造并没有太大的帮助,因为对于
void
和非
void
的情况,你会得到非常不同的结果。也许
f(x)
仍然是
x
但是
f(y)
void
,我们会得到
foo(x,x)
tuple
但是
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)...);
}
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), ...);
}
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)...);
};