首页 > 解决方案 > 模板重载在模板类中的行为不同

问题描述

在以下代码中产生(LiveExample):

类模板指针

类模板指针

模板指针

大小为 10 的模板数组

#include <iostream>
#include <utility>
#include <type_traits>

template <class TVar>
class CVar
{
public:
    void classTemplate(TVar *) const
    {
        std::cout << "Class template pointer\n";
    }

    template<unsigned sz>
    void classTemplate(TVar(&)[sz]) const
    {
         std::cout << "Class template array with size " << sz << "\n";
    }

};

template<typename T>
void regTemplate(T)
{
    std::cout << "Template pointer\n";
}

template<typename T, unsigned sz> void regTemplate(T(&)[sz])
{
    std::cout << "Template array with size " << sz << "\n";
}

int main()
{
  unsigned int test[10] = {};

  CVar<unsigned> *cFoo = new CVar<unsigned>();
  cFoo->classTemplate(&test[0]);
  cFoo->classTemplate(test);

  regTemplate(&test[0]);
  regTemplate(test);
}
  1. 为什么当我在类中重载模板时,它无法解析所需的功能——cFoo->classTemplate(test);即被调用,那么响应将是Class template array with size 10

  2. 如何在不改变的情况下在 1 中达到我想要的结果cFoo->classTemplate(test);?请注意,void CVar<TVar>::classTemplate(TVar(&)[sz]) const如果需要,可能会更改

标签: c++arraystemplatespointerstemplate-specialization

解决方案


在其他条件相同的情况下,重载决议更喜欢非模板而不是模板。万一,一个重载是函数模板,而classTemplate另一个是非模板成员函数。

以防万一,regTemplate两者都是函数模板:选择带有数组的模板是因为它更专业。实际上,如果您将第一个重载更改为 take T*,调用就会变得模棱两可。


推荐阅读