当前位置: 首页 > 知识库问答 >
问题:

使用SFINAE启用转换运算符

沈嘉瑞
2023-03-14

T是基本类型时,我试图使用SFINAE重载运算符T()以返回一个副本,当T是一个类时,我试图重载一个常量引用。

在我下面的示例中,当使用double时,我无法删除第二个重载(使用std::is_class)。

也就是说,我得到的错误是:

error: no type named ‘type’ in ‘struct std::enable_if<false, const double&>’
operator typename std::enable_if< std::is_class<T>::value, const T&>::type () const
^

我做错了什么?

#include <iostream>
#include <type_traits>

template<typename T>
struct Foo
{
    operator typename std::enable_if<!std::is_class<T>::value, T >::type () const
    {
        return _val;
    }

    operator typename std::enable_if< std::is_class<T>::value, const T&>::type () const
    {
        return _val;
    }

    T _val;
};

int main()
{
    Foo<double> f1;
    f1._val = 0.3;

    double d = f1;
    std::cout << d << std::endl;
    return 0;
}

共有2个答案

楮法
2023-03-14

虽然没有解决为什么不丢弃错误运算符的问题,但要解决手头的特定问题,即通过const ref返回类类型,或通过值返回其他类类型,可以使用std::conditional找到解决方案。

template< bool B, class T, class F >
struct conditional;

提供成员typedef type,如果B在编译时为true,则定义为T;如果B为false,则定义为F。

工作示例:

#include <iostream>
#include <type_traits>

template<typename T>
struct Foo
{
    operator typename std::conditional<
        std::is_class<T>::value, const T&, T>::type () const
    {
        return _val;
    }

    T _val;
};

int main()
{
    Foo<double> f1;
    f1._val = 0.3;

    double d = f1;
    std::cout << d << std::endl;
    return 0;
}
燕扬
2023-03-14

在实例化类成员函数时,T是已知的,因此不会发生替换,而是会出现一个硬错误,而不是SFINAE。最简单的解决方法是为那些运算符重载引入一个伪模板参数,并将其默认为T,以便仍然可以进行类型推断。

template<typename U = T>
operator typename std::enable_if<!std::is_class<U>::value, U >::type () const
{
    return _val;
}

template<typename U = T>
operator typename std::enable_if< std::is_class<U>::value, const U&>::type () const
{
    return _val;
}

现场演示

 类似资料:
  • 基本上,我希望我的范围类型可以从

  • JLS说 编辑:如果操作数已经使用转换运算符转换为不同的(较小的)类型,那么操作数是否经历数字提升(一元/二进制)?如果是这种情况,您将如何解释具有字节变量的表达式,因为在强制转换之后,字节结果可能会根据数字提升转换为int?

  • 下面的代码将泛型(POD)类型包装成(模板)类,并定义内部模板转换操作符,以便能够在兼容(但不同)类型之间进行隐式转换。我希望代码是相当自我解释的。在任何情况下,我都无法理解为什么将转换为另一个POD都能正常工作,但将(此处键入为)转换为)却失败得很 有什么想法吗?代码如下:

  • C++ 运算符 强制转换运算符是一种特殊的运算符,它把一种数据类型转换为另一种数据类型。强制转换运算符是一元运算符,它的优先级与其他一元运算符相同。 大多数的 C++ 编译器都支持大部分通用的强制转换运算符: (type) expression 其中,type 是转换后的数据类型。下面列出了 C++ 支持的其他几种强制转换运算符: const_cast<type> (expr): const

  • 模板输出进可以使用几个运算符: 加法: {$a+$b} 减法: {$a-$b} 乘法: {$a \* $b} 除法: {$a/$b} 取余: {$a%$b} ++: {$a++} {++$a} --: {$a--} {--$a} 综合运算: {$a+$b+$c*$d}

  • 请参考:http://www.kancloud.cn/manual/thinkphp/1798