【问题标题】:Is there a way to specialize a templated function to discriminate when the type of an argument is a pointer from when it is not?有没有办法专门化模板函数来区分参数的类型何时是指针,何时不是?
【发布时间】:2019-07-24 21:48:45
【问题描述】:

让我们考虑那些模板化的函数

template <typename T> void Func(T* p)
{
  printf("pointer ");
  Func(*p);
}

template <typename T> void Func(T)
{
  printf("type");
}

我想编写它们,以便如果我给一个带有多个指针类型的参数,则以指针类型专门化的函数被递归调用到不再有指针的点,最后调用没有指针的函数。 通常,如果我写

int a;
int* a2 = &a;
int** a3 = &a2;
int*** a4 = &a3;
Func(a4);

我希望输出写入

pointer pointer pointer type

不幸的是,如果我这样写,我得到的只是对非指针函数的调用。

有什么方法可以实现吗?

【问题讨论】:

  • 在 C++17 中,您可以完全摆脱一个重载,只需使用 Func(T) 使用 if constexprstd::is_pointer 来测试 T 是否是指针,例如:template &lt;typename T&gt; void Func(T param) { if constexpr (std::is_pointer_v&lt;T&gt;) { printf("pointer "); Func(*p); } else { printf("type"); } 参见Simplifying templates and #ifdefs with if constexpr,其中有与您类似的示例。
  • 注意它是重载,而不是特化。

标签: c++ pointers templates specialization


【解决方案1】:

您只需要交换功能。在template &lt;typename T&gt; void Func(T* p) 中,当您执行Func(*p); 时,编译器所知道的所有内容都是template &lt;typename T&gt; void Func(T* p)。因此,您最终会递归调用相同的函数,直到当您不再有指针时它会出错。如果你使用

template <typename T> void Func(T)
{
  printf("type");
}

template <typename T> void Func(T* p)
{
  printf("pointer ");
  Func(*p);
}

那么当你调用Func(*p); 时,编译器会知道template &lt;typename T&gt; void Func(T) 并会在你不再有指针给你时调用

pointer pointer pointer type

【讨论】:

  • 致 OP。即使这样,您也不能使用 int*** a; Func(a); 您必须将 a 初始化为有效指针。否则,Func(*p) 将导致未定义的行为。
  • 我没有想过申报顺序的重要性。这有点违反直觉,但我相信这是有道理的,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多