【问题标题】:template specialization with template parameter带有模板参数的模板特化
【发布时间】:2015-06-12 16:46:34
【问题描述】:

我最近开始学习 c++。而且我有时会与模板专业化混淆。有人能告诉我为什么以下 No(3) 的模板专业化是非法的吗?

template<typename T>  // No (1)
class ClassA {
public:
    ClassA();
    virtual ~ClassA();

    void func(void);
};

template<>  // No (2)
void ClassA<int>::func(void) {}   // Ok legal specialization

template<typename T>  // No (3)
void ClassA<int>::func(void) {}   // error by compiler

似乎 No (3) 处的模板特化没有隐式模板参数,因为类型名 T 是 int。但是编译器给出以下错误,

error: prototype for ‘void ClassA<int>::func()’ does not match any in class ‘ClassA<int>’ void ClassA<int>::func(void) {
                           ^

error: candidate is: void ClassA<T>::func() [with T = int] void func(void);
                          ^

恐怕我在问一个愚蠢的问题,但我真的很想知道错误的原因。我想知道 1 号和 3 号的类型名 T 是否相同。请告诉我他们。非常感谢。

【问题讨论】:

  • (2) 和 (3) 都不应该编译
  • 在 C++ 中,您通常会写成 func() 而不是 func(void)。后者只允许向后兼容 C。

标签: c++ templates


【解决方案1】:

(2)是写特化的方式。

(1) 和(3) 中的T 并不完全一样,你可以写(非专业化):

template <typename U>
void ClassA<U>::func(void) {}

而在 (1) 中是 T

或部分专业

template <typename T>
void ClassA<std::vector<T>>::func(void) {}

这里 (1) 中的 T1 将是 std::vector&lt;T3&gt;。

【讨论】:

  • 非常感谢 Jarod42。这是我想知道的。但如果是这样,我想知道为什么我们不能只写 void ClassA::func(void) {} 而不是 template void ClassA::func(void) {}?我觉得第一个模板让我很困惑。
  • 我认为它是具有单一语法和连贯语法(带有N甚至0模板参数)。另请注意,语法必须管理模板类 (template &lt;T&gt; template &lt;U&gt; void A&lt;T&gt;::foo(U)) 和显式实例化 (template class A&lt;int&gt;;) 的模板方法。
【解决方案2】:

代替

template<typename T>
void ClassA<int>::func(void) {}

使用

template<typename T>
void ClassA<T>::func(void) {}
        // ^^^ T, not it.

我不确定使用 int 是故意还是疏忽。

【讨论】:

  • 他们的问题似乎是关于声明其模板的 &lt;int&gt; 特化,而不是一般模板定义。
  • 嗨,想你回答它,coryKramer。这是故意的。我将 No (1) 处的模板参数设置为 int,但我也有意将类型名 T 放在 No(3) 处,因为我认为 No(3) 处的 T 被推导出为 int。
猜你喜欢
  • 2012-12-07
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 2011-05-10
  • 2017-01-20
相关资源
最近更新 更多