简体   繁体   English

有模板成员 - 模板模板扣除

[英]Has template member - template template deduction

Say I have the two following test-classes: 假设我有以下两个测试类:

struct TestYes {
    using type = void;
    template <typename... T>
    using test = void;
};

struct TestNo { };

and I want to determine if they have this template member test . 我想确定他们是否有这个模板成员test

For the member type , 对于会员type

template <typename, typename = void>
struct has_type_impl {
    using type = std::false_type;
};
template <typename T>
struct has_type_impl<T, typename T::type> {
    using type = std::true_type;
};
template <typename T>
using has_type = typename has_type_impl<T>::type;

works perfectly: 完美的工作:

static_assert( has_type<TestYes>::value, ""); // OK
static_assert(!has_type<TestNo>::value, "");  // OK

but the equivalent for the template member test : 但模板成员test的等价物:

template <typename, template <typename...> class = std::tuple>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, T::template test> {
    using type = std::true_type;
};
template <typename T>
using has_test = typename has_test_impl<T>::type;

fails on 失败了

static_assert( has_test<TestYes>::value, "");

I know I can use SFINAE like: 我知道我可以使用SFINAE:

template <typename T>
struct has_test_impl {
private:
    using yes = std::true_type;
    using no = std::false_type;

    template <typename U, typename... Args>
    static auto foo(int) -> decltype(std::declval<typename U::template test<Args...>>(), yes());

    template <typename> static no foo(...);

public:
    using type = decltype(foo<T>(0));
};

template <typename T>
using has_test = typename has_test_impl<T>::type;

but I'm wondering why the compiler is correctly deducting the partial specialization of has_type_impl while it remains on the first definition of has_test_impl . 但我想知道为什么编译器正确地扣除了has_type_impl的部分has_type_impl而它仍然是has_test_impl的第一个定义。

Thanks in advance for your enlightenment! 在此先感谢您的启发!

template<template<class...> class...>
using void_templ = void;

template <typename, typename = void>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, void_templ<T::template test>> {
    using type = std::true_type;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM