【问题标题】:Why member template method have to be specialized using template<> outside of class为什么成员模板方法必须在类外使用 template<> 专门化
【发布时间】:2015-12-12 12:00:44
【问题描述】:

我不清楚编译器何时以及如何创建template 函数。所以我无法解释以下 2 个示例的行为。

示例 1。

struct C1 {                                                    
    template <typename T>
    void g(T t);
};

template<>   
void C1::g(double x) {
    cout << "Member templates. C1::g(double) " << x << endl;
}

上面的代码构建并运行。但是,如果没有 template&lt;&gt;,g++ 就会抱怨。

error: prototype for ‘void C1::g(double)’ does not match any in class ‘C1’

但是如果我将 g(double ) 的定义放在类中就可以了。

问题 1: 为什么成员模板方法必须在类外使用 template 专门化?

示例 2。

struct C1 {                                                          
    template <typename T>
    void g(T t);

    void g(double x) {
        cout << "C1::g(double): " << x << endl;
    }
};

template<>
void C1::g(double x) {
    cout << "Member templates. C1::g(double) " << x << endl;
}

C1 c;
c.g(10.5); // output: C1::g(double): 10.5

成员模板模板 void g() 未被调用。这让我想知道

问题 2。 成员模板是否曾经被专门化过?

【问题讨论】:

  • 因为它是一个模板函数。不是函数重载。
  • @CoffeeandCode 谢谢。例如 1。 C1 中没有 g() 的声明。没有 template 的 g() 的定义看起来“自然”(对我来说)被解释为模板专业化。我认为编译器拥有消除定义歧义所需的一切。

标签: c++ templates c++11


【解决方案1】:

成员模板模板 void g() 未被调用。这让我想知道

这里是函数重载问题,非模板函数将在重载决议中获得模板特化。

http://en.cppreference.com/w/cpp/language/overload_resolution

最佳可行函数

对于每对可行函数F1和F2,从第i个参数到第i个参数的隐式转换序列进行排序以确定哪个更好(除了第一个参数,静态成员函数的隐式对象参数对排名没有影响)

如果 F1 的所有参数的隐式转换不比 F2 的所有参数的隐式转换差,则确定 F1 是比 F2 更好的函数,并且

1) F1 的至少一个参数的隐式转换优于 F2 的该参数的相应隐式转换

2) 或。如果不是这样,(仅在非类通过转换初始化的情况下),从 F1 的返回类型到正在初始化的类型的标准转换序列优于从 F2 的返回类型的标准转换序列

3) 或者,如果不是,F1 是非模板函数,而 F2 是模板特化

4) 或者,如果不是,F1 和 F2 都是模板特化,根据模板特化的部分排序规则,F1 更加特化

您可以显式调用模板特化函数:

c.g<>(10.5); // output: Member templates. C1::g(double) 10.5

LIVE

【讨论】:

  • 如果是这样,我想模板专业化永远不会完成。我将研究重载决议顺序。谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多