【问题标题】:Function template specialization and the Abrahams/Dimov example函数模板特化和 Abrahams/Dimov 示例
【发布时间】:2013-02-09 07:39:00
【问题描述】:

(我假设知道这个问题中的Abrahams/Dimov example。)

假设在这样的标头中有一些第 3 方代码,您无法修改:

template<class T> void f(T);    // (1) base template 1
template<class T> void f(T *);  // (2) base template 2
template<> void f<>(int *);     // (3) specialization of (2)

问题是:

如果我已按原样获得上述声明,是否有可能我现在可以针对 T = int *(例如)的情况专门化基本模板 1?

或者仅仅声明基本模板 2 是否意味着基本模板 1 不能再被特化(至少对于指针而言)?

【问题讨论】:

  • 即使可以,该专业化是否可以调用?如果使用指针调用 f ,则基本模板 2 似乎总是“获胜”。
  • @Mat:据我所知,不是来自当前的翻译单元,但我认为它可以从另一个翻译单元调用,对吧?假设另一个翻译单元具有#1 和相应特化的非重载声明。
  • 一个在范围内没有基本模板 2 的 TU? (不确定我是否理解。)还要注意 ODR 违规行为。
  • @Mat:是的,我就是这个意思。另一个翻译单元可以只声明第一个基本模板及其所有特化,但避免定义特化。当前 TU 中定义的专业化将可以通过这种方式调用。
  • 如果函数不在同一个头文件中,你可以尝试#includeing他们在不同的命名空间

标签: c++ template-specialization function-templates


【解决方案1】:

您可以通过在函数名称后面的尖括号中显式指定模板参数来重载 (1)(参见 C++11-Standard 14.7.3)

#include <iostream>
using namespace std;
template<class T> void f(T)    // (1) base template 1
{
    cout << "template<class T> void f(T)" << endl;
}

template<class T> void f(T *)  // (2) base template 2
{
    cout << "template<class T> void f(T *)" << endl;
}
//template<> void f<>(int *);     // (3) specialization of (2)

template<> void f<int*>(int *)     // (4) specialization of (1)
{
    cout << "f<int*>(int *)" << endl;
}


int main() {
    int i;
    f(&i); // calls (2) since only base-templates take part in overload resolution
    return 0;
}

【讨论】:

  • 正确,虽然它不是“过载”。这是一个明确的专业化。
  • 您是否也可以通过执行template &lt;&gt; void f&lt;int&gt;(int *) { ... } 来明确地重载(2)?这就是注释掉的 (3) 行所推断的吗?
  • @SamWhitlock:在当前示例中:是的。在这种情况下,专业化 template&lt;&gt; void f&lt;&gt;(int *);template &lt;&gt; void f&lt;int&gt;(int *) 是相同的。
【解决方案2】:

您总是可以尝试然后来找我们。但我不明白为什么它不起作用。如果T = int* 它将按您的意愿工作。因此没有 2 将是 int* * 的参数

【讨论】:

  • 我把这个例子搞砸了吗?对我来说,专门针对 T = int * 似乎需要与 (3) (template&lt;&gt; void f&lt;&gt;(int *);) 完全相同的语法,因此不可能......
  • @Mehrdad 你说得很对。它不能完成:) 除非你找到一种方法来强制特定的重载(你可以利用的功能的其他一些差异)
  • @Mehrdad 我明白了:您可以使用= 和隐式转换operators 创建一个类,它们是int,但是使您的函数重载,将类本身放入(因此它会选择那个而不是 int 的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多