【问题标题】:Clang, MSVC, GCC disagree about compiling this code with function application in index_sequenceClang、MSVC、GCC 不同意使用 index_sequence 中的函数应用程序编译此代码
【发布时间】:2021-11-27 23:42:18
【问题描述】:

这段代码是从answer到另一个问题:

template <typename F, std::size_t ... Is>
constexpr auto apply(F f, std::index_sequence<Is...>)
-> std::index_sequence<f(Is)...>
{
    return {};
}

gcc 失败

<source>:5:29: error: expected parameter pack before '...'

msvc 和 clang 编译它。

现在改成这个会导致 msvc 失败:

template <typename F, std::size_t ... Is>
constexpr auto apply(F , std::index_sequence<Is...>)
-> std::index_sequence<F{}(Is)...>
{
    return {};
}
<source>(5): error C2187: syntax error: '<end Parse>' was unexpected here 
<source>(5): error C2059: syntax error: '('
<source>(6): error C2988: unrecognizable template declaration/definition 
<source>(6): error C2059: syntax error: '{'
<source>(6): error C2143: syntax error: missing ';' before '{''
<source>(6): error C2447: '{': missing function header (old-style formal list?)

这在 C++ 标准中是模糊的还是只是一个实现错误?我看不出为什么在这个地方不允许函数调用,对于 F{} 的构造也是如此。

【问题讨论】:

  • @xskxzr 你需要#include &lt;cstddef&gt; #include &lt;utility&gt;
  • 如果你想让它工作:godbolt.org/z/dz5rdKnsT
  • 考虑到f(Is) 是模板参数列表中的模板参数,根据temp.variadic#5.7,这应该是一个有效的包扩展。
  • clang 怎么样?

标签: c++ g++ language-lawyer c++20 clang++


【解决方案1】:
  1. 这段代码来自김선달上面的评论:
#include <utility>
#include <type_traits>

template<typename F, typename Seq>
struct apply_impl;

template<typename F, std::size_t... Is>
struct apply_impl<F, std::index_sequence<Is...>> {
  private:
    static constexpr auto test(F, std::index_sequence<Is...>)
    -> decltype(std::index_sequence< F{}(Is)... > {});
  public:
    using type = decltype(test(F{}, std::index_sequence<Is...>{}));
};

template<typename F, typename Seq>
using apply = typename apply_impl<F, Seq>::type;

constexpr auto f = [](auto x) -> std::size_t { return x*x; };

using res_type = apply<decltype(f), std::index_sequence<0, 1, 2, 3, 4> >;

static_assert(std::is_same<res_type, std::index_sequence<0, 1, 4, 9, 16>>::value);
  1. 这是来自Mechap上面的评论

    template-argument-list ([temp.arg]); 中,模式是template-argument。来自docs

注意:提供解决方案作为答案而不是评论。

【讨论】:

    猜你喜欢
    • 2020-06-03
    • 1970-01-01
    • 2015-04-23
    • 2020-03-26
    • 2022-10-18
    • 2017-10-17
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多