如果每个参数都可以转换为特定类型,则启用ctor

0xb*_*00d 2 c++ type-traits enable-if c++17

foo每当有多个参数并且每个参数都可以转换为类型时,我想启用类的ctor value_type.我尝试过以下方法:

struct foo
{
    using value_type = /* some type */;

    template<class... Ts,
        std::enable_if_t<(sizeof...(Ts) > 0) && std::conjunction_v<std::is_convertible_v<Ts, value_type>...>, int> = 0>
    explicit foo(Ts&&... vs)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

假设foo::value_type = float.我试图声明foo bar{ 1 };并观察到ctor被禁用了.为了看看发生了什么,我std::conjunction_v从模板中删除了部分并添加了

static_assert(std::conjunction_v<std::is_convertible_v<Ts, value_type>...>, "");
Run Code Online (Sandbox Code Playgroud)

对身体.现在我的编译器(MSVC 14.1/Clang)产生错误

模板类型参数的模板参数必须是类型

static_assert(std::conjunction_v<std::is_convertible_v<Ts, value_type>...>, "");               
                             // ^
Run Code Online (Sandbox Code Playgroud)

这究竟是什么问题?c

ken*_*ytm 7

完全如上所述,模板类型参数的模板参数必须是类型.在std::conjunction<T...>,Ts被假定为类型,但std::is_convertible_v<X, Y>直接产生值.

试试这个:

std::conjunction_v<std::is_convertible<Ts, value_type>...>
//                                    ^ no `_v`.
Run Code Online (Sandbox Code Playgroud)

顺便说一下,既然您的目标是C++ 17,那么可以使用fold表达式而不是std::conjunction:

template<class... Ts,
  std::enable_if_t<((sizeof...(Ts) > 0) && ... && std::is_convertible_v<Ts, value_type>), int> _ = 0
>
Run Code Online (Sandbox Code Playgroud)