【发布时间】: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;
}
它只是尝试恢复传递的参数并对其应用一些函数。
对于 G++,它编译得很好,但对于 clang++(甚至来自中继),它会给出以下错误:
错误:没有匹配的函数调用“apply_inverse”
我认为原因是这样的事实,在上层重载中,函数原型中的参数包后面有一个参数。但是参数包中所有参数的类型都是明确指定的。
编译器接受代码对吗?
【问题讨论】:
-
@T.C.由于参数包的工作方式,在这种情况下,clang 不正确吗?
-
我认为它没有被指定,但是让所有显式指定的类型参数都被参数声明列表中的第一个(此处未推导)参数包使用的 g++ 方法听起来并不合理.另一方面,可以显式提供非推导参数,所以...¯\_(ツ)_/¯
标签: c++ g++ variadic-templates clang++ c++17