连接一元参数的模板参数包 [英] Concatenating template parameter packs for a unary argument
问题描述
虽然说 std :: add_pointer
是一元的,但以下代码已被GCC 7.0.0(20160608)和Clang 3.9.0接受:
Although, say, std::add_pointer
is unary, the following code is accepted by both GCC 7.0.0 (20160608) and Clang 3.9.0:
template <typename ...Ts>
struct tc1 {
using a = std::add_pointer<Ts...>;
};
但是,尽管Clang接受了以下代码,但GCC拒绝了它:
However, while the following code is accepted by Clang, it is rejected by GCC:
template <typename ...Ts>
struct tc2 {
template <typename ...Us>
using b = std::add_pointer<Ts...,Us...>;
};
这是有效的C ++吗?从句法上讲,我可以想象当包装为空时,逗号是一个问题,但是大概在其他情况下它会被忽略.例如, std :: common_type
接受零个或多个参数,而对于任何一个编译器,以下内容都没有问题:
Is this valid C++? Syntactically, I could imagine that the comma is a problem when packs are empty, but presumably it is elided on other occasions; for example, std::common_type
accepts zero or more arguments, and the following presents no problem for either compiler:
template <typename ...Ts>
struct tc3 {
template <typename ...Us>
using c = std::common_type<Ts...,Us...>;
};
推荐答案
您可以将此代码用于任意数量的模板参数 tc3< 1或更多> :: a<零或更多>
,在GCC和Clang上:
You can use this code for any number of template arguments tc3<1 or more>::a<zero or more>
, on GCC and Clang:
#include <type_traits>
struct A {
template<typename ...Args> A(Args ... args) {}
};
template <typename T, typename ...Ts>
struct tc3 {
template <typename ...Us>
using c = std::add_pointer<T(Ts...,Us...)>;
};
int main() {
typedef tc3<A, int, float>::template c<unsigned, double>::type ptr;// A(*)(int,float,unsigned,double)
typedef tc3<A>::template c<>::type ptr2; // A(*)()
typedef tc3<bool>::template c<int, int>::type ptr3; // bool(*)(int,int)
typedef std::add_pointer<bool(int, int)>::type ptr4; // bool(*)(int,int)
return 0;
}
- GCC 7.0.0: http://melpon.org/wandbox/permlink/m7Re0kFevMjalv6s
- Clang 4.0.0: http://melpon.org/wandbox/permlink/mXDtQRN7COxhtLN8
但是,当Clang接受以下代码时,它会被拒绝通过GCC:
However, while the following code is accepted by Clang, it is rejected by GCC:
下面的代码仅在实例化之前被Clang接受,但是在出现错误之后:
This following code is accepted by Clang only before instantinationed, but after there is error:
template <typename ...Ts>
struct tc2 {
template <typename ...Us>
using b = std::add_pointer<Ts...,Us...>;
};
- 错误Clang 4.0: http://melpon.org/wandbox/permlink/vpBCJHlvWk1ai1ny
- 错误GCC 7.0.0: http://melpon.org/wandbox/permlink/a1rRfDI5zcUz3nau
std :: add_pointer<>
只能接受一个临时参数:
std::add_pointer<>
can take only one tamplte argument: http://en.cppreference.com/w/cpp/types/add_pointer
template< class T >
struct add_pointer;
一个以上的参数只能在内部的 namespace
详细信息中使用,也可以在其他一些参数中使用:
More than one argument it can take only in internal namespace
detail or in some else:
可能的实施方式:
namespace detail {
template< class T, bool is_function_type = false >
struct add_pointer {
using type = typename std::remove_reference<T>::type*;
};
template< class T >
struct add_pointer<T, true> {
using type = T;
};
template< class T, class... Args >
struct add_pointer<T(Args...), true> {
using type = T(*)(Args...);
};
template< class T, class... Args >
struct add_pointer<T(Args..., ...), true> {
using type = T(*)(Args..., ...);
};
} // namespace detail
template< class T >
struct add_pointer : detail::add_pointer<T, std::is_function<T>::value> {};
这样做是为了支持以下代码:
This is done to support this code:
typedef std::add_pointer<bool(int, int)>::type ptr4; // bool(*)(int,int)
这篇关于连接一元参数的模板参数包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!