[英]type trait for function pointer?
我需要在模板 class 中有条件地使用std::abs
或std::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.