嵌套结构的专业化特征

问题描述 投票:3回答:2

我有一个带有嵌套模板结构的模板结构。

template <int F>
struct foo
{
    template <int B>
    struct bar {
        static constexpr int f = F;
        static constexpr int b = B;
    };
 };

我想创造一个像这样的特质

template <class>
struct is_foo_bar : std::false_type { };

template <int F, int B>
struct is_foo_bar< foo<F>::bar<B> > : std::true_type { };

static_assert(is_foo_bar< foo<1>::bar<2> >::value);

这给出了一个错误:

type/value mismatch at argument 1 in template parameter list for ‘template<class> struct is_foo_bar’<br>
struct is_foo_bar<foo<F>::bar<B>> : std::true_type { };

如果我把bar拿出来的话

template <int F, int B>
struct foo_bar {
    static constexpr int f = F;
    static constexpr int b = B;
};

template <int F>
struct foo
{
    template <int B>
    using bar = foo_bar<F, B>;
};

template <class>
struct is_foo_bar : std::false_type { };

template <int F, int B>
struct is_foo_bar< foo_bar<F, B> > : std::true_type { };

static_assert(is_foo_bar< foo<1>::bar<2> >::value);

... 有用。但这不是我想要的方式。我在Qazxswpoi声明在bar的代码中缺少什么?

c++11 templates template-specialization typetraits template-deduction
2个回答
0
投票

我在Qazxswpoi声明在foo的代码中缺少什么?

在编写部分专业化时,你已经忘记了barfoo

typename

但真正的问题是,第一个template模板值,template <int F, int B> struct is_foo_bar< typename foo<F>::template bar<B> > : std::true_type { }; // not deducible ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ deducible context ,在int之前,所以不可推导。

您可以定义此部分特化,但从不使用。


0
投票

使用SFINAE可以通过这种方式解决

F

这是有效的,但您需要明确指定所有参数,这可能是一个问题(例如,变量参数)。

编辑:找到可变参数的解决方案

::

这确保template <class, class = void> struct is_foo_bar : std::false_type { }; template <class T> struct is_foo_bar< T, std::enable_if_t< std::is_same_v< T, typename foo<T::f>::template bar<T::b> > > > : std::true_type { }; 属于template <int F> struct foo { template <int B, class... Params> struct bar { static constexpr int f = F; static constexpr int b = B; static constexpr size_t size = sizeof...(Params); }; }; template <class, class = void> struct is_foo_bar : std::false_type { }; template <template <int, class...> class T, int B, class... Params> struct is_foo_bar< T<B, Params...>, std::enable_if_t< std::is_same_v< T<B, Params...>, typename foo< T<B, Params...>::f >::template bar<B, Params...> > > > : std::true_type { }; template <int, class...> struct not_foo_bar { static constexpr int f = 0; }; static_assert(is_foo_bar< foo<1>::bar<2> >::value); static_assert(is_foo_bar< foo<1>::bar<2, int> >::value); static_assert(not is_foo_bar< not_foo_bar<1> >::value); static_assert(not is_foo_bar< not_foo_bar<1, int> >::value); 。当没有这样的要求时,用barfoo测试所需成员的存在应该不那么难看......

© www.soinside.com 2019 - 2024. All rights reserved.