我有一个带有嵌套模板结构的模板结构。
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
的代码中缺少什么?
我在Qazxswpoi声明在
foo
的代码中缺少什么?
在编写部分专业化时,你已经忘记了bar
和foo
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
之前,所以不可推导。
您可以定义此部分特化,但从不使用。
使用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);
。当没有这样的要求时,用bar
和foo
测试所需成员的存在应该不那么难看......