当前位置: 首页 > 知识库问答 >
问题:

为什么不允许成员函数的模板专门化?

梁俊友
2023-03-14

如果我有一些琐碎的东西,比如(为了澄清,我并不是说这是一个好的实现,只是一个演示成员函数部分模板专门化失败的示例):

template <typename T, typename U>
class BankAccount
{
  T money;
  U interestRate;
public:
  BankAccount(T money, U interestRate) :
    money(money), interestRate(interestRate)
  {}

  void showMeTheMoney();
};

我无法通过执行以下操作来专门化每个功能:

// invalid code
template <typename U>
void BankAccount <int, U>::showMeTheMoney()
{
  printf("$%d.00 interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <long, U>::showMeTheMoney()
{
  printf("$%l.00 interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <float, U>::showMeTheMoney()
{
  printf("$%.2f interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <double, U>::showMeTheMoney()
{
  printf("$%.2f interest: %f\n", money, interestRate);
}

int main(int argc, char *argv[])
{
  BankAccount<double, float> b(500, 0.03);
  b.showMeTheMoney();
  BankAccount<std::uint64_t, float> c(1234, 0.01);
  c.showMeTheMoney();
}

不幸的是,C标准不允许:

14.5.5.31、类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配。

因此,唯一的解决方案(据我所知)是使用类型特征或用样板代码复制整个类。这个决定背后是否有一个基本原理,或者这是C语言中根本不存在的,因为没有足够的需求,或者其他一些原因?

共有1个答案

丰景同
2023-03-14

因为它不是您编写的成员函数的模板专门化。这是班级的专业化。因此,代码应该是这样的(我添加了一个公共基类,您不必为所有规范定义成员):

template <typename T, typename U>
class BankAccountBase
{
protected:
    T money;
    U interestRate;

public:
    BankAccountBase(T money, U interestRate) :
        money(money), interestRate(interestRate)
    {}
};

template <typename T, typename U>
class BankAccount
{
    T money;
    U interestRate;
public:
    BankAccount(T money, U interestRate) :
        money(money), interestRate(interestRate)
    {}

    void showMeTheMoney();
};

template <typename U>
class BankAccount <int, U> : public BankAccountBase <int, U>
{
public:
    BankAccount(int money, U interestRate) :BankAccountBase(money, interestRate) { }
    void showMeTheMoney();
};

template <typename U>
class BankAccount <long, U> : public BankAccountBase <long, U>
{
public:
    BankAccount(long money, U interestRate) :BankAccountBase(money, interestRate) { }
    void showMeTheMoney();
};
template <typename U>
class BankAccount <float, U> : public BankAccountBase <float, U>
{
    BankAccount(float money, U interestRate) :BankAccountBase(money, interestRate) { }
public:
    void showMeTheMoney();
};
template <typename U>
class BankAccount <double, U> : public BankAccountBase <double, U>
{
public:
    BankAccount(double money, U interestRate) :BankAccountBase(money, interestRate) { }
    void showMeTheMoney();
};

template <typename U>
class BankAccount <long long, U> : public BankAccountBase <long long, U>
{
public:
    BankAccount(long long money, U interestRate) :BankAccountBase(money, interestRate) { }
    void showMeTheMoney();
};


// invalid code
template <typename U>
void BankAccount <int, U>::showMeTheMoney()
{
    printf("$%d.00 interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <long, U>::showMeTheMoney()
{
    printf("$%l.00 interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <long long, U>::showMeTheMoney()
{
    printf("$%l.00 interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <float, U>::showMeTheMoney()
{
    printf("$%.2f interest: %f\n", money, interestRate);
}

template <typename U>
void BankAccount <double, U>::showMeTheMoney()
{
    printf("$%.2f interest: %f\n", money, interestRate);
}

int main(int argc, char *argv[])
{
    BankAccount<double, float> b(500, 0.03);
    b.showMeTheMoney();
    BankAccount<long long, float> c(1234, 0.01);
    c.showMeTheMoney();
}
 类似资料:
  • 我有以下模板方法: 但是我得到了那些奇怪的链接错误: /usr/lib/gcc/x86_64-redhat-linux/4.4。7/../../../../包括/c/4.4。7/例外:62:void MyStruct::readField(std::basic_istream)的多重定义 如何专门化此成员函数? 编辑 这种方法在以下方面起作用: 或者使用s或在类外使用

  • 让我们考虑以下代码: 我知道第二个声明是重载,而不是部分专业化: 但我想知道它与部分专业化有何不同?它为我们提供了与部分专业化相同的功能,不是吗?

  • 我试图调用一个模板类成员函数专门化,它从类的构造函数中返回一个值,但我似乎找不到正确的语法(如果存在的话)。下面是我的代码,下面是来自编译器(而不是链接器)的错误消息。 错误消息:g++-std=c++11-o t1 t1.cpp t1.cpp:19:18:错误:在'constexpr'模板constexpr const char*name()之前需要'<';^T1.CPP:22:26:错误:“c

  • 顺便说一句,我确实编译了以下内容,但是专门化在运行时没有像预期的那样工作。基类型和派生类型最终要经历的非专用版本。 正确的语法是什么?

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。