SFINAE enable_if显式构造函数 [英] SFINAE enable_if explicit constructor

查看:67
本文介绍了SFINAE enable_if显式构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过 enable_if 在显式和隐式转换构造函数之间进行切换。

I'm trying to switch between an explicit and an implicit conversion constructor via enable_if.

我的代码当前看起来是

#include <type_traits>
#include <cstdint>

enum class enabled {};

template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type;
template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type;

template <std::intmax_t A> struct SStruct
{
    static constexpr std::intmax_t a = A;
};

template <typename T> struct SCheckEnable : std::integral_constant<bool, T::a == 0>
{
};

template <typename U, typename T> class CClass
{
    public:
        template <typename T2, enable_if_t<SCheckEnable<U>::value, enabled>...> constexpr CClass(T2 v) : val(v) {};
        template <typename T2, disable_if_t<SCheckEnable<U>::value, enabled>...> explicit constexpr CClass(T2 v) : val(v) {};

    private:
        T val;
};

int main()
{
    CClass<SStruct<0>, double> a = 1;                             // should use implicit constructor
    CClass<SStruct<1>, double> b = CClass<SStruct<1>, double>(1); // should use explicit constructor
}

true enable_if 中的code>取决于模板参数 U

The true in the enable_ifs is dependent of the template parameter U

如果我尝试使用 g ++ 4.9.1 -std = c ++ 11 编译此最小示例启用code>时出现以下错误

If I try to compile this minimal example with g++ 4.9.1 and --std=c++11 enabled I get the following errors

sfinae.cpp: In substitution of ‘template<bool B, class T> using disable_if_t = typename std::enable_if<(! B), T>::type [with bool B = true; T = enabled]’:
sfinae.cpp:13:52:   required from here
sfinae.cpp:7:95: error: no type named ‘type’ in ‘struct std::enable_if<false, enabled>’
 template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type;
                                                                                               ^
sfinae.cpp:19:68: error: prototype for ‘constexpr CClass<U, T>::CClass(T2)’ does not match any in class ‘CClass<U, T>’
 template <typename U, typename T> template <typename T2> constexpr CClass<U, T>::CClass(T2 v) : val(v)
                                                                    ^
sfinae.cpp:13:77: error: candidates are: template<class U, class T> template<class T2, int ...<anonymous> > constexpr CClass<U, T>::CClass(T2)
   template <typename T2, disable_if_t<true, enabled>...> explicit constexpr CClass(T2 v);
                                                                             ^
sfinae.cpp:12:67: error:                 template<class U, class T> template<class T2, enabled ...<anonymous> > constexpr CClass<U, T>::CClass(T2)
   template <typename T2, enable_if_t<true, enabled>...> constexpr CClass(T2 v);
                                                                   ^

任何想法如何根据参数<$ c在显式和隐式构造之间进行选择$ c> U 在这里?

Any idea how to select between explicit and implicit construction based on parameter U here?

推荐答案

使用

template <class...> struct null_v : std::integral_constant<int, 0> {};

并将构造函数定义为

template <typename T2,
          long = null_v<enable_if_t<SCheckEnable<U>::value, T2>>::value>
constexpr CClass(T2 v) : val(v) {};

template <typename T2,
          int = null_v<disable_if_t<SCheckEnable<U>::value, T2>>::value>
explicit constexpr CClass(T2 v) : val(v) {};

使参数依赖并实际实例化。
演示

Making the argument dependent and actually instantiated. Demo.

[温度扣除] / 8:

[temp.deduct]/8:


如果替代结果在无效的类型或表达式中,类型
推导失败。一个无效的类型或表达式是如果使用替换参数编写的格式将是
的格式错误。

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments.

在您的情况下,该错误发生在任何替换之外,因此这不会导致推论失败,反而会使您的代码格式错误。

In your case the error occurs outside of any substitution, so that's not causing a deduction failure but rather makes your code ill-formed.

这篇关于SFINAE enable_if显式构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆