部分模板特化 SFINAE

3

我有以下的类模板:

template<bool head, bool... tail> 
struct var_and {
    static constexpr bool value = head && var_and<tail...>::value;
};

template<bool b> struct var_and<b> {
    static constexpr bool value = b;
};

template<typename... Ts>
struct type_list {};

template <typename T, typename Enable = void>
class foo;

template <typename... T>
class foo<type_list<T...>, std::enable_if_t<var_and<std::is_integral_v<T>...>::value>> {};

当我尝试匹配专业时:

foo<type_list<int, int, int>> test{};

我遇到了一个错误:

Error C2079 'test' uses undefined class 'ECS::foo<ECS::type_list<int,int,int>,void>'

同时我还收到了以下错误:

more than one partial specialization matches the template argument list of class "ECS::foo<ECS::type_list<int, int, int>, void>" 
"ECS::foo<ECS::type_list<T...>, std::enable_if_t<ECS::var_and<std::is_integral_v<T>...>::value, void>>"          
"ECS::foo<ECS::type_list<T...>, std::enable_if_t<ECS::var_and<std::is_integral_v<T>...>::value, void>>"
... (The exact same error message 6 more times)

我该如何使用SFINAE来强制实现对可变类型包中类型的类型特征?

我已经成功地将其应用于单个类型参数:

http://www.cppsamples.com/common-tasks/class-template-sfinae.html

我知道可以使用static_assert,但我想知道是否也可以不使用。


1
从编译器的输出来看,你好像在使用msvc。这段代码在gcc和clang下运行得非常完美(参见http://coliru.stacked-crooked.com/a/36b9eecd91763aaf)...所以,是msvc的bug吗?要不然就是你没有提供所有被编译的代码 :) - Rerito
这段代码在使用msvc编译时会产生相同的错误:http://rextester.com/NIU85113。所以我认为这是一个bug? - M. Bijman
实际上,我现在注意到该链接显示了一个略微不同的错误。但是,在http://webcompiler.cloudapp.net/上运行相同的代码会产生相同的错误,并且它使用了更近期的编译器。 - M. Bijman
1个回答

1
“解决方法可能如下所示:”
#include <type_traits>

template <bool...>
struct bool_pack { };

template <bool... Bs>
using var_and = std::is_same<bool_pack<true, Bs...>, bool_pack<Bs..., true>>;

template<typename... Ts>
struct type_list {};

template <typename T, typename Enable = void>
class foo;

template <typename... T>
class foo<type_list<T...>, std::enable_if_t<var_and<std::is_integral<T>::value...>::value>> {};

int main()
{
    foo<type_list<int, int, int>> {};
}

[实时演示]


用你的var_and替换我的确实编译通过了。有趣...这是MSVC已知的问题吗? - M. Bijman
不确定... std::is_integral_v<T> 的使用似乎也有问题,我将其替换为std::is_integral<T>::value - W.F.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接