【问题标题】:Alias a templated function给模板化函数取别名
【发布时间】:2014-10-03 17:56:29
【问题描述】:

您可以使用 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&lt;T&gt;() 缩短为仅DurationCast&lt;T&gt;(),而不是简单地走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);

【问题讨论】:

  • 仅供参考,duration_caststd::chrono;不仅仅是std。我想using std::chrono; 避免在所有std 中啜泣同样不在你的视线范围内,尽管几乎每个人 最终都会这样做。
  • 哎呀,我知道。固定问题。
  • @derpface:您可以模板化作为函数指针的变量,但是您必须指定所有参数,例如DurationCast&lt;std::chrono::milliseconds, float, std::ratio&lt;1&gt;&gt;(s),这个适合你吗?
  • @derpface:或者至少在声明之前知道,什么是表示和期限
  • 相对确定你必须包装函数而不是使用typedef - 你可以typedef 函数指针,但不是函数AFAIK(请纠正并@reference 我在评论中如果我我错了!)

标签: c++


【解决方案1】:

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

你可以给函数指针类型的变量起别名:

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&lt;T&gt;() 缩短为 DurationCast&lt;T&gt;()

函数指针的诀窍在于,您必须指定所有类型的参数才能获取函数的地址,因此,您需要显式给出或模板化所有参数的类型。不幸的是,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

【讨论】:

  • 这很好地回答了这个问题! (与接受的答案不同)特别是,我需要这个来更改哪些模板参数是必要的(实际上是 0)。您能否评论一下您是否真的会使用它来支持更易于理解的函数调用,这可能会被内联?
  • 好答案。使用auto(例如template &lt;typename T&gt; auto foo_alias = &amp;foo&lt;T&gt;;)会变得更好。
【解决方案2】:

你可以创建一个辅助函数转发到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);
}

【讨论】:

  • "并且不用自己编写函数对象来实现吗?"但我同意,除了#define
  • 哎呀,我在编辑帖子之前没有刷新页面,但这基本上是我得出的结论,除了没有auto/decltype。
猜你喜欢
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多