Unify type and non-type template parameters

倖福魔咒の 提交于 2019-12-23 07:21:42

问题


I have a type trait that checks if a given type is an instance of a given class template:

template <template <typename...> class C, typename T>
struct check_is_instance_of : std::false_type { };

template <template <typename...> class C, typename ...Ts>
struct check_is_instance_of<C, C<Ts...>> : std::true_type { };

template <template <typename...> class C, typename T>
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { };

Unfortunately, this does not work for non-type template parameters as they are not "captured" by the variadic template parameters, so

is_instance_of<std::integral_constant, std::true_type>

yields a compile-error. Is there any way to write an implementation of is_instance_of that works for an arbitrary number of type and non-type template parameters?


回答1:


I don't think there is a clean way to do this unless the non-type arguments are all of the same type and you know which type it is. In that very specific case, function overloading can be used.

In any other case, you end up in a template-argument version of the perfect forwarding problem where you would have to specialize for every type/nontype argument combination.

If you only need to address homogeneous non-template arguments and you can guess the type, the following should work. You can overload instance_of for different types (only int is covered here), but you'd have to explicitly create an instance for each type you want to be able to handle:

// variation for non-type parameters, only for uniform parameters with
// known type.
template <typename V, template <V...> class C, typename T>
struct check_is_instance_of_nontype : std::false_type { };

template <typename V, template <V...> class C, V... Values>
struct check_is_instance_of_nontype<V, C, C<Values...>> : std::true_type { };

// this is as in your example
template <template <typename...> class C, typename T>
struct check_is_instance_of : std::false_type { };

template <template <typename...> class C, typename ...Ts>
struct check_is_instance_of<C, C<Ts...>> : std::true_type { };

template <template <typename...> class C, typename T>
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { };

template <template <typename...> class C, typename T>
constexpr bool instance_of()
{
    return is_instance_of< C, T>::value;
}

template <template <int...> class C, typename T>
constexpr bool instance_of()
{
    return check_is_instance_of_nontype< int, C, T>::value;
}

template< int... >
struct Duck
{
};

template<typename A, typename B>
struct Swallow
{

};

int main() {
    typedef Duck<1, 2> SittingDuck;
    typedef Swallow< int, int> UnladenSwallow;

    std::cout << instance_of< Duck, SittingDuck>() << instance_of< Swallow, UnladenSwallow>();
    return 0;
}


来源:https://stackoverflow.com/questions/29342064/unify-type-and-non-type-template-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!