如何对类型执行折叠表达

时间:2018-08-02 17:09:48

标签: c++ templates visual-studio-2017 variadic-templates

我尝试使用fold表达式询问我的类型是否可以转换为任何类型的可变参数模板类型,但是它不起作用。

我的尝试:

template<typename FromType, typename... ToType>
using enableIfPtrIsConvertible = std::enable_if_t<(false || std::is_convertible_v<FromType*, ToType*>...)>;

它不能编译:

error C2059:  syntax error: '...'
error C2976:  'std::enable_if_t': too few template arguments
     

...

有人可以帮助我吗?


我按照评论中的解释进行了尝试:

#include <type_traits>
template<typename FromType, typename... ToType>
using enableIfPtrIsConvertible = std::enable_if_t<(std::is_convertible_v<FromType*, ToType*> || ...)>;

class Base {};
class Derived :public Base {};

template <typename T, typename = enableIfPtrIsConvertible<T, Base, int>>
class Test {};

Test<Derived> tst1;

但是我仍然遇到这些编译器错误:

1>d:\vstest\odd\odd\isconvertible.h(3): error C2059: syntax error: '...'
1>d:\vstest\odd\odd\isconvertible.h(3): error C2976: 'std::enable_if_t': too few template arguments
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xtr1common(59): note: see declaration of 'std::enable_if_t'
1>d:\vstest\odd\odd\isconvertible.h(11): error C2976: 'Test': too few template arguments
1>d:\vstest\odd\odd\isconvertible.h(9): note: see declaration of 'Test'
1>d:\vstest\odd\odd\isconvertible.h(11): error C2133: 'tst1': unknown size
1>d:\vstest\odd\odd\isconvertible.h(11): error C2641: cannot deduce template argument for 'Test'

这个作品

template<typename FromType, typename... ToTypes>
constexpr bool is_ptr_convertible_v = (std::is_convertible_v<FromType*, ToTypes*> || ...);

template<typename FromType, typename... ToTypes>
using enableIfPtrIsConvertible = std::enable_if_t<is_ptr_convertible_v<FromType, ToTypes...>>;

但是我不明白为什么直接组合不能编译。

1 个答案:

答案 0 :(得分:3)

template<typename FromType, typename... ToType>
using enableIfPtrIsConvertible = std::enable_if_t<false || (std::is_convertible_v<FromType*, ToType*> || ...)>;

您折叠语法错误。问题与类型无关。

或者:

template<typename FromType, typename... ToType>
using enableIfPtrIsConvertible = std::enable_if_t<(std::is_convertible_v<FromType*, ToType*> || ...)>;

相同,但是更干净。