【问题标题】:Parameter with non-deduced type after parameter pack参数包后非推导类型的参数
【发布时间】:2017-05-06 20:51:17
【问题描述】:

clang++g++ 对于下一个程序有不同的行为:

#include <type_traits>
#include <utility>

template< std::size_t index, typename type >
struct ref { type & value; };

template< std::size_t index, typename type >
type && get(ref< index, type > const & r)
{
    return std::forward< type >(r.value);
}

template< typename F, typename ...types, std::size_t ...indices >
decltype(auto) apply_inverse(F & f, types &... values, std::index_sequence< indices... >)
{
    struct : ref< indices, types >... {} refs{{values}...};
    constexpr std::size_t top = sizeof...(indices) - 1;
    return std::forward< F >(f)(get< top - indices >(refs)...);
}

template< typename F, typename ...types >
decltype(auto) apply_inverse(F && f, types &&... values)
{
    return apply_inverse< F, types... >(f, values..., std::index_sequence_for< types... >{});
}

#include <iostream>

int main()
{
    auto const print = [] (auto const &... value) -> std::ostream & { return (std::cout << ... << value); };
    apply_inverse(print, 1, 2, 3) << std::endl;
}

Live example.

它只是尝试恢复传递的参数并对其应用一些函数。

对于 G++,它编译得很好,但对于 clang++(甚至来自中继),它会给出以下错误:

错误:没有匹配的函数调用“apply_inverse”

我认为原因是这样的事实,在上层重载中,函数原型中的参数包后面有一个参数。但是参数包中所有参数的类型都是明确指定的。

编译器接受代码对吗?

【问题讨论】:

  • @T.C.由于参数包的工作方式,在这种情况下,clang 不正确吗?
  • 我认为它没有被指定,但是让所有显式指定的类型参数都被参数声明列表中的第一个(此处未推导)参数包使用的 g++ 方法听起来并不合理.另一方面,可以显式提供非推导参数,所以...¯\_(ツ)_/¯

标签: c++ g++ variadic-templates clang++ c++17


【解决方案1】:

没有具体说明是哪个版本的 Clang 拒绝了上面的代码。

但此时 Clang 12 以及 GCC 和 MSVC 都接受了它: https://gcc.godbolt.org/z/qMc9fKTEf

所以代码是完全合法的。

【讨论】:

    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    相关资源
    最近更新 更多