繁体   English   中英

function 指针的类型特征?

[英]type trait for function pointer?

我需要在模板 class 中有条件地使用std::absstd::fabs ,这是简化版本中的相关代码:

template <typename T>
class C
{
public:
    using type = std::conditional_t<std::is_integral_v<T>, std::uint64_t, long double>;
    using check = std::is_integral<type>;

    // ERROR: mismatch in format parameter list
    constexpr auto ptr_abs = check::value ? &std::abs<check::value_type> : &std::fabs;

    // use pointer
    void use_ptr()
    {
        auto x = (*ptr_abs)(-3);
    }
};

没有一个尝试对我有用,我一无所知。

int main()
{
     C<int> a;
     a.f();

     C<float> b;
     b.f();
}

你真的需要使用 function 指针吗? 利用 C++ 类型安全机制不是更好吗? 如下:

template <typename T>
class C
{
public:
    using type = std::conditional_t<std::is_integral_v<T>, std::uint64_t, long double>;
    static const bool check = std::is_integral_v<type>;

    std::function<type(type)> abs = [](auto arg)
    {
        if constexpr (check) return std::abs(static_cast<long long>(arg));
        else return std::fabs(arg);
    };

    void use()
    {
        auto x = abs(-3);
    }
};

对我很有效 请注意,无符号整数没有std::abs ,因此,为避免歧义,我必须通过强制转换来选择特定的重载(在本例中为long long ;我不知道什么是Result )。


在没有if constexpr的 C++17 之前,您可以通过使用模板特化来实现更多输入。

用指针的类型解决 function 过载:

#include <cmath>
#include <type_traits>
#include <cstdlib>
#include <iostream>

template <typename T>
class C {
public:
    static constexpr T (*ptr_abs)(T) = &std::abs;
    void f() {
        std::cout << typeid(ptr_abs).name() << "\n";
        auto x = (*ptr_abs)(-3);
    }
};

int main()
{
     C<int> a;
     a.f(); // PFiiE
     C<float> b;
     b.f(); // PFffE
     C<double> c;
     c.f(); // PFddE
}

也许我误解了你的问题,但在我看来,你可以单独定义你想要的abs版本,然后在其他类中使用它

#include <cmath>
#include <cstdint>
#include <complex>
#include <iostream>
#include <limits>
#include <type_traits>
#include <typeinfo>

namespace my {

template <class T>
auto abs_(T x)
{
    if constexpr ( std::is_unsigned_v<T> ) {
        return static_cast<uintmax_t>(x);
    }
    else if constexpr ( std::is_integral_v<T> ) {
        return static_cast<uintmax_t>(std::abs(static_cast<intmax_t>(x)));
    }
    else {
        return std::fabs(static_cast<long double>(x));
    }  
}

template <class T>
auto abs_(std::complex<T> const& x)
{
    return std::abs(static_cast<std::complex<long double>>(x));
}

}

template <typename T>
class C
{
public:
    void use(T x)
    {
        std::cout << typeid(T).name() << ' ' << x;
        auto a = my::abs_(x);
        std::cout << ' ' << typeid(a).name() << ' ' << a << '\n';
    }
};

int main()
{
    C<int> a;
    a.use(-42);

    C<float> b;
    b.use(-0.1);

    C<long long> c;
    c.use(std::numeric_limits<long long>::min());

    C<size_t> d;
    d.use(-1);

    C<std::complex<double>> e;
    e.use({-1, 1});
}

在此处测试。

暂无
暂无

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

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