尽管比方说,std::add_pointer
是一元的,但 GCC 7.0.0 (20160608) 和 Clang 3.9.0 都接受以下代码:
template <typename ...Ts>
struct tc1 {
using a = std::add_pointer<Ts...>;
};
但是,虽然以下代码被 Clang 接受,但被 GCC 拒绝:
template <typename ...Ts>
struct tc2 {
template <typename ...Us>
using b = std::add_pointer<Ts...,Us...>;
};
这是有效的 C++ 吗?从句法上讲,我可以想象当包为空时逗号是个问题,但大概在其他情况下它被省略了;例如,std::common_type
接受零个或多个参数,并且以下内容对任一编译器都没有问题:
template <typename ...Ts>
struct tc3 {
template <typename ...Us>
using c = std::common_type<Ts...,Us...>;
};
最佳答案
您可以将此代码用于任意数量的模板参数 tc3<1 or more>::a<zero or more>
, 关于 GCC 和 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;
}
- 海湾合作委员会 7.0.0:http://melpon.org/wandbox/permlink/m7Re0kFevMjalv6s
- Clang 4.0.0:http://melpon.org/wandbox/permlink/mXDtQRN7COxhtLN8
However, while the following code is accepted by Clang, it is rejected by GCC:
以下代码仅在实例化之前被 Clang 接受,但在出现错误之后:
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<>
只能接受一个模板参数:http://en.cppreference.com/w/cpp/types/add_pointer
template< class T >
struct add_pointer;
它只能在内部接受多个参数 namespace
细节或其他方面:
可能的实现:
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> {};
这样做是为了支持这段代码:
typedef std::add_pointer<bool(int, int)>::type ptr4; // bool(*)(int,int)
关于c++ - 连接一元参数的模板参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37923660/