繁体   English   中英

具有std :: is_same的std :: enable_if拒绝编译

[英]std::enable_if with std::is_same refuses to compile

以下代码无法编译

#include <type_traits>
#include <fftw3.h>

template<class Real>
class foo
{
public:
    foo(Real* x, size_t length,
        typename std::enable_if<std::is_same<double, Real>::value>::type* = nullptr)
    {
        y = fftw_alloc_real(length);
        fftw_plan plan = fftw_plan_r2r_1d(length, x, y, FFTW_REDFT10, FFTW_ESTIMATE);
        fftw_execute_r2r(plan, x, y);
        fftw_destroy_plan(plan);
    }

    foo(Real* x, size_t length,
        typename std::enable_if<std::is_same<float, Real>::value>::type* = nullptr)
    {
        y = fftwf_alloc_real(length);
        fftwf_plan plan = fftwf_plan_r2r_1d(length, x, y, FFTW_REDFT10, FFTW_ESTIMATE);
        fftwf_execute_r2r(plan, x, y);
        fftwf_destroy_plan(plan); 
    }


private:
    Real* y;
};

int main()
{
    std::vector<double> x{12, 83, 96.3};
    foo<double> fd(x.data(), x.length());

    std::vector<float> xf{12, 82, 96.2};
    foo<float> ff(x.data(), x.length());
}

给出错误信息

test.cpp:14:33: error: no type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration
    typename std::enable_if<std::is_same<float, Real>::value>::type* = nullptr)

我的语法或对std::enable_if理解有什么问题,导致无法编译? 解决办法是什么,以便我可以使用仍从FFTW调用非模板代码的模板?

让我们从编译器的角度出发。 当您说foo<double> ,您将使用Real = double实例化模板foo

当我们遇到第一个构造函数时,我们评估enable_if ,发现typename std::enable_if<std::is_same<double, Real>::value>::typevoid (因为std::is_same<double, double>::value == true )。 一切都很好。

当遇到第二个构造函数时,我们再次尝试通过评估enable_if实例化它。 但是,这次的typename std::enable_if<std::is_same<float, Real>::value>::type不存在,因为std::is_same<float, double>::value == false 这是一个错误。


每当您尝试实例化foo ,这两个构造函数中的至少一个都会格式错误。 如果您希望SFINAE参与进来,则需要对构造函数进行模板化:

template<class Real>
class foo
{
public:
    template <typename T>
    foo(T x,
        typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr)
    {
        mantissa_bits = 52;
    }

    template <typename T>
    foo(T x,
        typename std::enable_if<std::is_same<float, T>::value>::type* = nullptr)
    {
        mantissa_bits = 23;
    }


private:
    size_t mantissa_bits;
};

尽管我通常看到支持SFINAE的构造函数如下所示:

    template <typename T, typename std::enable_if<std::is_same<double, T>::value, int>::type = 0>
    foo(T x)
    {
        mantissa_bits = 52;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM