gpt4 book ai didi

c++ - 提取模板类默认参数

转载 作者:行者123 更新时间:2023-11-30 03:55:50 25 4
gpt4 key购买 nike

有没有办法在编译时只知道非特化模板类就提取模板类的默认参数?

我知道如何提取实例化模板类的参数,如下所示:

// Just an example class for the demonstration
template<class A, class B=void>
struct example {};

// Template parameters storage class
template<class...An>
struct args;

// MPL utility that extracts the template arguments from a template class
template<class C>
struct get_args
{
typedef args<> type;
};
template<template<class...> class C, class...An>
struct get_args< C<An...> >
{
typedef args<An...> type;
};

// And the assertion
static_assert(
std::is_same
< args<int,void>,
get_args< example<int> >::type
>::value,
"Check this out"
);

现在我想知道的是,是否可以使用 decltype 或其他任何东西来仅从非专用模板类中检索默认模板参数:

// MPL utility that extract template default arguments from a template class
template<template<class...> class C>
struct get_default_args
{
typedef /* what goes here? */ type;
};

// And the assertion
static_assert(
std::is_same
< args<void>,
get_default_args< example >::type
>::value,
"Check this out"
);

目前,我只想出了如何提取模板类的参数数量,而不是它们的默认值:

namespace detail {
template< template<class> class >
boost::mpl::size_t<1> deduce_nb_args();
template< template<class,class> class >
boost::mpl::size_t<2> deduce_nb_args();
template< template<class,class,class> class >
boost::mpl::size_t<3> deduce_nb_args();
/* ... and so on ... */
}

// MPL utility that extract the number of template arguments of a template class
template<template<class...> class C>
struct get_nb_args :
decltype(detail::deduce_nb_args<C>()) {};

// And the assertion
static_assert(
get_nb_args< example >::value == 2,
"Check this out"
);

编辑

似乎最后,MSVC 又一次阻止我执行此操作。类似下面的内容会使编译器崩溃并出现 fatal error C1001:编译器中发生内部错误。

template<template<class...> class D> static
boost::boost::mpl::int_<0> mandatory(D<>*)
{ return boost::boost::mpl::int_<0>(); }
template<template<class...> class D> static
boost::mpl::int_<1> mandatory(D<void>*)
{ return boost::mpl::int_<0>(); }
template<template<class...> class D> static
boost::mpl::int_<2> mandatory(D<void,void>*)
{ return boost::mpl::int_<0>(); }
template<template<typename...> class D> static
boost::mpl::int_<-1> mandatory(...)
{ return boost::mpl::int_<-1>(); }

int check()
{
return mandatory<example>(nullptr);
}

尝试下一个导致error C2976: 'D' : too few template arguments

template<template<class,class> class D> static
boost::mpl::int_<0> mandatory2(D<>*)
{ return boost::mpl::int_<0>(); }
template<template<class,class> class D> static
boost::mpl::int_<1> mandatory2(D<void>*)
{ return boost::mpl::int_<0>(); }
template<template<class,class> class D> static
boost::mpl::int_<2> mandatory2(D<void,void>*)
{ return boost::mpl::int_<0>(); }

int check2()
{
return mandatory2<example>(nullptr);
}

所以在我看来,无论采用何种方法,MSVC 都禁止使用默认参数对模板类进行编程实例化。反过来,我看起来不可能使用 SFINAE 技术来提取:1.强制参数个数;2.默认参数的类型。

编辑2

好的,经过多次测试,似乎是在尝试仅使用默认参数以编程方式实例化模板类时发生的 MSVC 错误。

我提交了错误报告 here还有一个here .

这是一个 traits 类,它允许使用给定的模板参数检查一个类是否可实例化,这不会导致编译器崩溃,但对于完全默认的可实例化类不计算为 true

namespace detail {
typedef std::true_type true_;
typedef std::false_type false_;

template< template<class...> class D, class...An >
true_ instantiable_test(D<An...>*);
template< template<class...> class D, class...An >
false_ instantiable_test(...);
}
template< template<class...> class C, class...An >
struct is_instantiable : decltype(detail::instantiable_test<C,An...>(nullptr)) {};

也就是说,MSVC 似乎不可能检索使用默认参数实例化的模板类型。通常以下内容不会编译:

template< template<class...> class T, class...An >
struct get_default_v0
{
typedef T<An...> type;
};

namespace detail {
template< template<class...> class T, class...An >
T<An...> try_instantiate();
} // namespace detail

template< template<class...> class T, class...An >
struct get_default_v1
{
typedef decltype(detail::try_instantiate<T,An...>()) type;
};

// C2976
static_assert(
std::is_same< get_default_v0<example,int> , example<int,void> >::value,
"v0"
);

// C2976
static_assert(
std::is_same< get_default_v1<example,int> , example<int,void> >::value,
"v1"
);

最佳答案

我会尝试这样的事情:

template <typename ...> struct Get2;

template <template <typename...> class Tmpl,
typename A, typename B, typename ...Rest>
struct Get2<Tmpl<A, B, Rest...>>
{
using type = B;
};

template <template <typename...> class Tmpl> struct GetDefault2
{
using type = typename Get2<Tmpl<void>>::type;
};

关于c++ - 提取模板类默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28858913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com