簡體   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