对模板化函数进行别名

Alias a templated function

本文关键字:别名 函数      更新时间:2023-10-16

您可以使用typedef为类型创建一个更短、更简单的名称:

typedef std::chrono::high_resolution_clock Clock;
typedef Clock::time_point TimePoint;
typedef std::chrono::seconds Seconds;
typedef std::chrono::milliseconds Milliseconds;

以及实例化的模板类型:

typedef std::chrono::duration<float, std::ratio<1>> RealDuration;
// Example usage
float dt = RealDuration(a - b).count();

对于函数指针:

typedef void (*FuncPtr)(int,int);

您也可以为模板使用类型别名:

template<typename T> using uptr = std::unique_ptr<T>;
// Example usage
uptr<int> myInt;
uptr<foo> myFoo;

但是,如何创建指向模板化函数的别名/指针呢?例如,如果我想使用DurationCast这个名称来写这样的东西:

x = DurationCast<Seconds>(a - b);
y = DurationCast<Milliseconds>(c - d);

需要做些什么才能将函数std::chrono::duration_cast<T>()缩短为仅DurationCast<T>(),而不需要简单地走using namespace std::chrono;using std::chrono::duration_cast;路线,也不需要编写自己的函数对象来实现它?

编辑:我想我可以写一个简单的包装:

template<typename ToType, typename FromType>
ToType DurationCast(const FromType& d)
{
    return std::chrono::duration_cast<ToType>(d);
}

它不像别名一样工作,但最终的结果是,我可以以与我的目标完全相同的方式使用它:

x = DurationCast<Seconds>(a - b);

如何创建指向模板化函数的别名/指针

您可以别名函数指针类型的变量:

template <typename T>
void foo()
{
    std::cout << "foo!" << (T)3.14f << std::endl;
}
template <typename T>
constexpr void(*foo_alias)() = &foo<T>;
int main()
{
   foo_alias<int>();    // 3
   foo_alias<float>();  // 3.14
}

例如,如果我想使用名称DurationCast(…),需要做些什么才能将函数std::chrono::duration_cast<T>()缩短为仅DurationCast<T>()

使用指向函数的指针的技巧是,必须指定所有类型的参数才能获得函数的地址,因此,需要显式给定或模板化所有参数的类型。不幸的是,std::chrono::duration_cast需要三个参数:

template <typename T, class Rep, class Period>
constexpr T(*DurationCast)(const std::chrono::duration<Rep, Period>&) = &std::chrono::duration_cast<T, Rep, Period>;
std::chrono::seconds s(1);
std::chrono::milliseconds ms = DurationCast<std::chrono::milliseconds, float, std::ratio<1>>(s);
//                                                                     ~~~~^  ~~~~~~~~~~~~^
//                                                       explicit representation and period

DEMO

您可以创建一个助手函数,该函数转发到duration_cast:

template <typename T, typename U>
auto DurationCast(U const& u) -> decltype(std::chrono::duration_cast<T>(u))
{
    return std::chrono::duration_cast<T>(u);
}