目前我能做到的是在线性时间内达到所需:
#include <type_traits>
#include <utility>
struct filler { template< typename type > operator type (); };
template< typename A, typename index_sequence = std::index_sequence<>, typename = void >
struct aggregate_arity
: index_sequence
{
};
template< typename A, std::size_t ...indices >
struct aggregate_arity< A, std::index_sequence< indices... >, std::__void_t< decltype(A{(indices, std::declval< filler >())..., std::declval< filler >()}) > >
: aggregate_arity< A, std::index_sequence< indices..., sizeof...(indices) > >
{
};
struct A0 {};
struct A1 { double x; };
struct A2 { int i; char c; };
struct C50 { template< typename ...Args, typename = std::enable_if_t< (sizeof...(Args) < 51) > > C50(Args &&...) { ; } };
static_assert(aggregate_arity< A0 >::size() == 0);
static_assert(aggregate_arity< A1 >::size() == 1);
static_assert(aggregate_arity< A2 >::size() == 2);
static_assert(aggregate_arity< C50 >::size() == 50);
如果术语“arity”不恰当,请纠正我。
我认为原则上是可能的:首先需要从一开始加倍元数试验,直到SFINAE失败(当然,以柔和的方式),然后使用二分法。
C50::C50(...)
中的类型是什么?operator type
模板参数没有默认值。 - Tomilov Anatoliystruct {} dummy = some_type_list<Args...> {};
的代码来明确地触发错误(希望编译器能够提供足够好的诊断信息),以此来验证filler
是否正常工作。 - Luc Danton