【问题标题】:How to use SFINAE to enable implicitness of explicitness of the conversion operator?如何使用 SFINAE 启用转换运算符的显式隐性?
【发布时间】:2018-10-29 15:35:58
【问题描述】:

考虑以下代码:

// Preamble
#include <iostream>
#include <type_traits>

// Wrapper
template <class From>
struct wrapper
{
    // Implicit conversion
    template <class To, class = typename std::enable_if<
        std::is_convertible<From, To>::value
    >::type>
    constexpr operator To() const noexcept;

    // Explicit conversion
    template <class To, class = typename std::enable_if<
        !std::is_convertible<From, To>::value
        && std::is_constructible<To, From>::value
    >::type>
    explicit constexpr operator To() const noexcept;
};

// Main
int main(int argc, char* argv[])
{
    wrapper<int> x;
    double y = x;
    return 0;
}

理想情况下,当From 可隐式转换为To 时,此代码将隐式转换运算符,并在To 可从From 显式构造时使转换运算符显式。

但是,代码当前无法编译,因为从编译器的角度来看,两个转换运算符具有相同的签名。

问题:是否有任何方法可以欺骗编译器以产生预期的行为?


答案:完整代码基于Quentin的答案:

// Preamble
#include <iostream>
#include <type_traits>

// Wrapper
template <class From>
struct wrapper
{
    // Implicit conversion
    template <class To, typename std::enable_if<
        std::is_convertible<From, To>::value,
    int>::type = 0>
    constexpr operator To() const noexcept(noexcept(From{})) {
        return From{};
    }

    // Explicit conversion
    template <class To, typename std::enable_if<
        !std::is_convertible<From, To>::value
        && std::is_constructible<To, From>::value,
    int>::type = 0>
    explicit constexpr operator To() const noexcept(noexcept(From{})) {
        return From{};
    }
};

// Main
int main(int argc, char* argv[])
{
    wrapper<int> x;
    double y = x;
    return 0;
}

【问题讨论】:

    标签: c++11 implicit-conversion sfinae explicit conversion-operator


    【解决方案1】:

    是的,只需将您的 class = typename std::enable_if&lt;...&gt;::type 模式替换为 typename std::enable_if&lt;..., int&gt;::type = 0。那么 SFINAE 参数是一个不同类型的非类型模板参数,并且函数会正确重载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多